Home | History | Annotate | Line # | Download | only in acpisrc
      1 /******************************************************************************
      2  *
      3  * Module Name: asconvrt - Source conversion code
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "acpisrc.h"
    153 
    154 AS_BRACE_INFO               Gbl_BraceInfo[] =
    155 {
    156     {" if",         3},
    157     {" else if",    8},
    158     {" else while", 11},
    159     {" else",       5},
    160     {" do ",        4},
    161     {NULL,          0}
    162 };
    163 
    164 
    165 /* Local prototypes */
    166 
    167 static char *
    168 AsMatchValidToken (
    169     char                    *Buffer,
    170     char                    *Filename,
    171     char                    TargetChar,
    172     AS_SCAN_CALLBACK        Callback);
    173 
    174 static char *
    175 AsCheckBracesCallback (
    176     char                    *Buffer,
    177     char                    *Filename,
    178     UINT32                  LineNumber);
    179 
    180 static UINT32
    181 AsCountLines (
    182     char                    *Buffer,
    183     char                    *Filename);
    184 
    185 
    186 #define MODULE_HEADER_BEGIN "/******************************************************************************\n *\n * Module Name:";
    187 #define MODULE_HEADER_END   " *****************************************************************************/\n\n"
    188 #define INTEL_COPYRIGHT     " * Copyright (C) 2000 - 2025, Intel Corp.\n"
    189 
    190 /* Opening signature of the Intel legal header */
    191 
    192 char        *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice";
    193 
    194 UINT32      NonAnsiCommentCount;
    195 
    196 char        CopyRightHeaderEnd[] = INTEL_COPYRIGHT " *\n" MODULE_HEADER_END;
    197 
    198 /******************************************************************************
    199  *
    200  * FUNCTION:    AsCountNonAnsiComments
    201  *
    202  * DESCRIPTION: Count the number of "//" comments. This type of comment is
    203  *              non-ANSI C.
    204  *
    205  * NOTE: July 2014: Allows // within quoted strings and within normal
    206  *       comments. Eliminates extraneous warnings from this utility.
    207  *
    208  ******************************************************************************/
    209 
    210 void
    211 AsCountNonAnsiComments (
    212     char                    *Buffer,
    213     char                    *Filename)
    214 {
    215 
    216     AsMatchValidToken (Buffer, Filename, 0, NULL);
    217 
    218     /* Error if any slash-slash comments found */
    219 
    220     if (NonAnsiCommentCount)
    221     {
    222         AsPrint ("Non-ANSI // Comments Found", NonAnsiCommentCount, Filename);
    223         Gbl_NonAnsiComments += NonAnsiCommentCount;
    224     }
    225 }
    226 
    227 
    228 /******************************************************************************
    229  *
    230  * FUNCTION:    AsCheckForBraces
    231  *
    232  * DESCRIPTION: Check for an open brace after each if/else/do (etc.)
    233  *              statement
    234  *
    235  ******************************************************************************/
    236 
    237 void
    238 AsCheckForBraces (
    239     char                    *Buffer,
    240     char                    *Filename)
    241 {
    242 
    243     AsMatchValidToken (Buffer, Filename, 0, AsCheckBracesCallback);
    244 }
    245 
    246 
    247 /******************************************************************************
    248  *
    249  * FUNCTION:    AsCheckBracesCallback
    250  *
    251  * DESCRIPTION: Check if/else/do statements. Ensure that braces
    252  *              are always used.
    253  *
    254  * TBD: Currently, don't check while() statements. The problem is that there
    255  * are two forms: do {} while (); and while () {}.
    256  *
    257  ******************************************************************************/
    258 
    259 static char *
    260 AsCheckBracesCallback (
    261     char                    *Buffer,
    262     char                    *Filename,
    263     UINT32                  LineNumber)
    264 {
    265     char                    *SubBuffer = Buffer;
    266     char                    *NextBrace;
    267     char                    *NextSemicolon;
    268     AS_BRACE_INFO           *BraceInfo;
    269 
    270 
    271     for (BraceInfo = Gbl_BraceInfo; BraceInfo->Operator; BraceInfo++)
    272     {
    273         if (!(strncmp (BraceInfo->Operator, SubBuffer, BraceInfo->Length)))
    274         {
    275             SubBuffer += (BraceInfo->Length - 1);
    276 
    277             /* Find next brace and the next semicolon */
    278 
    279             NextBrace = AsMatchValidToken (SubBuffer, Filename, '{', NULL);
    280             NextSemicolon = AsMatchValidToken (SubBuffer, Filename, ';', NULL);
    281 
    282             /* Next brace should appear before next semicolon */
    283 
    284             if ((!NextBrace) ||
    285                (NextSemicolon && (NextBrace > NextSemicolon)))
    286             {
    287                 Gbl_MissingBraces++;
    288 
    289                 if (!Gbl_QuietMode)
    290                 {
    291                     printf ("Missing braces for <%s>, line %u: %s\n",
    292                         BraceInfo->Operator + 1, LineNumber, Filename);
    293                 }
    294             }
    295 
    296             return (SubBuffer);
    297         }
    298     }
    299 
    300     /* No match, just return original buffer */
    301 
    302     return (Buffer);
    303 }
    304 
    305 
    306 /******************************************************************************
    307  *
    308  * FUNCTION:    AsMatchValidToken
    309  *
    310  * DESCRIPTION: Find the next matching token in the input buffer.
    311  *
    312  ******************************************************************************/
    313 
    314 static char *
    315 AsMatchValidToken (
    316     char                    *Buffer,
    317     char                    *Filename,
    318     char                    TargetChar,
    319     AS_SCAN_CALLBACK        Callback)
    320 {
    321     char                    *SubBuffer = Buffer;
    322     char                    *StringStart;
    323     UINT32                  TotalLines;
    324 
    325 
    326     TotalLines = 1;
    327     NonAnsiCommentCount = 0;
    328 
    329     /* Scan from current position up to the end if necessary */
    330 
    331     while (*SubBuffer)
    332     {
    333         /* Skip normal comments */
    334 
    335         if ((*SubBuffer == '/') &&
    336             (*(SubBuffer + 1) == '*'))
    337         {
    338             /* Must maintain line count */
    339 
    340             SubBuffer += 2;
    341             while (strncmp ("*/", SubBuffer, 2))
    342             {
    343                 if (*SubBuffer == '\n')
    344                 {
    345                     TotalLines++;
    346                 }
    347                 SubBuffer++;
    348             }
    349 
    350             SubBuffer += 2;
    351             continue;
    352         }
    353 
    354         /* Skip single quoted chars */
    355 
    356         if (*SubBuffer == '\'')
    357         {
    358             SubBuffer++;
    359             if (!(*SubBuffer))
    360             {
    361                 break;
    362             }
    363 
    364             if (*SubBuffer == '\\')
    365             {
    366                 SubBuffer++;
    367             }
    368 
    369             SubBuffer++;
    370             continue;
    371         }
    372 
    373         /* Skip quoted strings */
    374 
    375         if (*SubBuffer == '"')
    376         {
    377             StringStart = SubBuffer;
    378             SubBuffer++;
    379             if (!(*SubBuffer))
    380             {
    381                 break;
    382             }
    383 
    384             while (*SubBuffer != '"')
    385             {
    386                 if ((*SubBuffer == '\n') ||
    387                     (!(*SubBuffer)))
    388                 {
    389                     AsPrint ("Unbalanced quoted string",1, Filename);
    390                     printf ("    %.32s (line %u)\n", StringStart, TotalLines);
    391                     break;
    392                 }
    393 
    394                 /* Handle escapes within the string */
    395 
    396                 if (*SubBuffer == '\\')
    397                 {
    398                     SubBuffer++;
    399                 }
    400 
    401                 SubBuffer++;
    402             }
    403 
    404             SubBuffer++;
    405             continue;
    406         }
    407 
    408         /* Now we can check for a slash-slash comment */
    409 
    410         if ((*SubBuffer == '/') &&
    411             (*(SubBuffer + 1) == '/'))
    412         {
    413             NonAnsiCommentCount++;
    414 
    415             /* Skip to end-of-line */
    416 
    417             while ((*SubBuffer != '\n') &&
    418                 (*SubBuffer))
    419             {
    420                 SubBuffer++;
    421             }
    422 
    423             if (!(*SubBuffer))
    424             {
    425                 break;
    426             }
    427 
    428             if (*SubBuffer == '\n')
    429             {
    430                 TotalLines++;
    431             }
    432 
    433             SubBuffer++;
    434             continue;
    435         }
    436 
    437         /* Finally, check for a newline */
    438 
    439         if (*SubBuffer == '\n')
    440         {
    441             TotalLines++;
    442             SubBuffer++;
    443             continue;
    444         }
    445 
    446         /* Normal character, do the user actions */
    447 
    448         if (Callback)
    449         {
    450             SubBuffer = Callback (SubBuffer, Filename, TotalLines);
    451         }
    452 
    453         if (TargetChar && (*SubBuffer == TargetChar))
    454         {
    455             return (SubBuffer);
    456         }
    457 
    458         SubBuffer++;
    459     }
    460 
    461     return (NULL);
    462 }
    463 
    464 
    465 /******************************************************************************
    466  *
    467  * FUNCTION:    AsRemoveExtraLines
    468  *
    469  * DESCRIPTION: Remove all extra lines at the start and end of the file.
    470  *
    471  ******************************************************************************/
    472 
    473 void
    474 AsRemoveExtraLines (
    475     char                    *FileBuffer,
    476     char                    *Filename)
    477 {
    478     char                    *FileEnd;
    479     int                     Length;
    480 
    481 
    482     /* Remove any extra lines at the start of the file */
    483 
    484     while (*FileBuffer == '\n')
    485     {
    486         printf ("Removing extra line at start of file: %s\n", Filename);
    487         AsRemoveData (FileBuffer, FileBuffer + 1);
    488     }
    489 
    490     /* Remove any extra lines at the end of the file */
    491 
    492     Length = strlen (FileBuffer);
    493     FileEnd = FileBuffer + (Length - 2);
    494 
    495     while (*FileEnd == '\n')
    496     {
    497         printf ("Removing extra line at end of file: %s\n", Filename);
    498         AsRemoveData (FileEnd, FileEnd + 1);
    499         FileEnd--;
    500     }
    501 }
    502 
    503 
    504 /******************************************************************************
    505  *
    506  * FUNCTION:    AsRemoveSpacesAfterPeriod
    507  *
    508  * DESCRIPTION: Remove an extra space after a period.
    509  *
    510  ******************************************************************************/
    511 
    512 void
    513 AsRemoveSpacesAfterPeriod (
    514     char                    *FileBuffer,
    515     char                    *Filename)
    516 {
    517     int                     ReplaceCount = 0;
    518     char                    *Possible;
    519 
    520 
    521     Possible = FileBuffer;
    522     while (Possible)
    523     {
    524         Possible = strstr (Possible, ".  ");
    525         if (Possible)
    526         {
    527             if ((*(Possible -1) == '.')  ||
    528                 (*(Possible -1) == '\"') ||
    529                 (*(Possible -1) == '\n'))
    530             {
    531                 Possible += 3;
    532                 continue;
    533             }
    534 
    535             Possible = AsReplaceData (Possible, 3, ". ", 2);
    536             ReplaceCount++;
    537         }
    538     }
    539 
    540     if (ReplaceCount)
    541     {
    542         printf ("Removed %d extra blanks after a period: %s\n",
    543             ReplaceCount, Filename);
    544     }
    545 }
    546 
    547 
    548 /******************************************************************************
    549  *
    550  * FUNCTION:    AsMatchExactWord
    551  *
    552  * DESCRIPTION: Check previous and next characters for whitespace
    553  *
    554  ******************************************************************************/
    555 
    556 BOOLEAN
    557 AsMatchExactWord (
    558     char                    *Word,
    559     UINT32                  WordLength)
    560 {
    561     char                    NextChar;
    562     char                    PrevChar;
    563 
    564 
    565     NextChar = Word[WordLength];
    566     PrevChar = * (Word -1);
    567 
    568     if (isalnum ((int) NextChar) ||
    569         (NextChar == '_')  ||
    570         isalnum ((int) PrevChar) ||
    571         (PrevChar == '_'))
    572     {
    573         return (FALSE);
    574     }
    575 
    576     return (TRUE);
    577 }
    578 
    579 
    580 /******************************************************************************
    581  *
    582  * FUNCTION:    AsPrint
    583  *
    584  * DESCRIPTION: Common formatted print
    585  *
    586  ******************************************************************************/
    587 
    588 void
    589 AsPrint (
    590     char                    *Message,
    591     UINT32                  Count,
    592     char                    *Filename)
    593 {
    594 
    595     if (Gbl_QuietMode)
    596     {
    597         return;
    598     }
    599 
    600     printf ("-- %4u %28.28s : %s\n", Count, Message, Filename);
    601 }
    602 
    603 
    604 /******************************************************************************
    605  *
    606  * FUNCTION:    AsTrimLines
    607  *
    608  * DESCRIPTION: Remove extra blanks from the end of source lines. Does not
    609  *              check for tabs.
    610  *
    611  ******************************************************************************/
    612 
    613 void
    614 AsTrimLines (
    615     char                    *Buffer,
    616     char                    *Filename)
    617 {
    618     char                    *SubBuffer = Buffer;
    619     char                    *StartWhiteSpace = NULL;
    620     UINT32                  SpaceCount = 0;
    621 
    622 
    623     while (*SubBuffer)
    624     {
    625         while (*SubBuffer != '\n')
    626         {
    627             if (!*SubBuffer)
    628             {
    629                 goto Exit;
    630             }
    631 
    632             if (*SubBuffer == ' ')
    633             {
    634                 if (!StartWhiteSpace)
    635                 {
    636                     StartWhiteSpace = SubBuffer;
    637                 }
    638             }
    639             else
    640             {
    641                 StartWhiteSpace = NULL;
    642             }
    643 
    644             SubBuffer++;
    645         }
    646 
    647         if (StartWhiteSpace)
    648         {
    649             SpaceCount += (SubBuffer - StartWhiteSpace);
    650 
    651             /* Remove the spaces */
    652 
    653             SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer);
    654             StartWhiteSpace = NULL;
    655         }
    656 
    657         SubBuffer++;
    658     }
    659 
    660 
    661 Exit:
    662     if (SpaceCount)
    663     {
    664         Gbl_MadeChanges = TRUE;
    665         AsPrint ("Extraneous spaces removed", SpaceCount, Filename);
    666     }
    667 }
    668 
    669 
    670 /******************************************************************************
    671  *
    672  * FUNCTION:    AsTrimWhitespace
    673  *
    674  * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines.
    675  *              this can happen during the translation when lines are removed.
    676  *
    677  ******************************************************************************/
    678 
    679 void
    680 AsTrimWhitespace (
    681     char                    *Buffer)
    682 {
    683     char                    *SubBuffer;
    684     int                     ReplaceCount = 1;
    685 
    686 
    687     while (ReplaceCount)
    688     {
    689         ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n",
    690             REPLACE_SUBSTRINGS, Buffer);
    691     }
    692 
    693     /*
    694      * Check for exactly one blank line after the copyright header
    695      */
    696 
    697     /* Find the header */
    698 
    699     SubBuffer = strstr (Buffer, HeaderBegin);
    700     if (!SubBuffer)
    701     {
    702         return;
    703     }
    704 
    705     /* Find the end of the header */
    706 
    707     SubBuffer = strstr (SubBuffer, "*/");
    708     SubBuffer = AsSkipPastChar (SubBuffer, '\n');
    709 
    710     /* Replace a double blank line with a single */
    711 
    712     if (!strncmp (SubBuffer, "\n\n", 2))
    713     {
    714         AsReplaceData (SubBuffer, 2, "\n", 1);
    715         AcpiOsPrintf ("Found multiple blank lines after copyright\n");
    716     }
    717 
    718     /* If no blank line after header, insert one */
    719 
    720     else if (*SubBuffer != '\n')
    721     {
    722         AsInsertData (SubBuffer, "\n", 1);
    723         AcpiOsPrintf ("Inserted blank line after copyright\n");
    724     }
    725 }
    726 
    727 
    728 /******************************************************************************
    729  *
    730  * FUNCTION:    AsReplaceHeader
    731  *
    732  * DESCRIPTION: Replace the default Intel legal header with a new header
    733  *
    734  ******************************************************************************/
    735 
    736 void
    737 AsReplaceHeader (
    738     char                    *Buffer,
    739     char                    *NewHeader)
    740 {
    741     char                    *SubBuffer;
    742     char                    *TokenEnd;
    743 
    744 
    745     /* Find the original header */
    746 
    747     SubBuffer = strstr (Buffer, HeaderBegin);
    748     if (!SubBuffer)
    749     {
    750         return;
    751     }
    752 
    753     /* Find the end of the original header */
    754 
    755     TokenEnd = strstr (SubBuffer, "*/");
    756     TokenEnd = AsSkipPastChar (TokenEnd, '\n');
    757 
    758     /* Delete old header, insert new one */
    759 
    760     AsReplaceData (SubBuffer, TokenEnd - SubBuffer,
    761         NewHeader, strlen (NewHeader));
    762 }
    763 
    764 
    765 /******************************************************************************
    766  *
    767  * FUNCTION:    AsDoSpdxHeader
    768  *
    769  * DESCRIPTION: Replace the default Intel legal header with a new header
    770  *
    771  ******************************************************************************/
    772 
    773 void
    774 AsDoSpdxHeader (
    775     char                    *Buffer,
    776     char                    *SpdxHeader)
    777 {
    778     char                    *SubBuffer;
    779 
    780 
    781     /* Place an SPDX header at the very top */
    782 
    783     AsReplaceData (Buffer, 0,
    784         SpdxHeader, strlen (SpdxHeader));
    785 
    786     /* Place an Intel copyright notice in the module header */
    787 
    788     SubBuffer = strstr (Buffer, MODULE_HEADER_END);
    789     if (!SubBuffer)
    790     {
    791         return;
    792     }
    793 
    794     AsReplaceData (SubBuffer, strlen (MODULE_HEADER_END),
    795         CopyRightHeaderEnd, strlen (CopyRightHeaderEnd));
    796 }
    797 
    798 /******************************************************************************
    799  *
    800  * FUNCTION:    AsReplaceString
    801  *
    802  * DESCRIPTION: Replace all instances of a target string with a replacement
    803  *              string. Returns count of the strings replaced.
    804  *
    805  ******************************************************************************/
    806 
    807 int
    808 AsReplaceString (
    809     char                    *Target,
    810     char                    *Replacement,
    811     UINT8                   Type,
    812     char                    *Buffer)
    813 {
    814     char                    *SubString1;
    815     char                    *SubString2;
    816     char                    *SubBuffer;
    817     int                     TargetLength;
    818     int                     ReplacementLength;
    819     int                     ReplaceCount = 0;
    820 
    821 
    822     TargetLength = strlen (Target);
    823     ReplacementLength = strlen (Replacement);
    824 
    825     SubBuffer = Buffer;
    826     SubString1 = Buffer;
    827 
    828     while (SubString1)
    829     {
    830         /* Find the target string */
    831 
    832         SubString1 = strstr (SubBuffer, Target);
    833         if (!SubString1)
    834         {
    835             return (ReplaceCount);
    836         }
    837 
    838         /*
    839          * Check for translation escape string -- means to ignore
    840          * blocks of code while replacing
    841          */
    842         if (Gbl_IgnoreTranslationEscapes)
    843         {
    844             SubString2 = NULL;
    845         }
    846         else
    847         {
    848             SubString2 = strstr (SubBuffer, AS_START_IGNORE);
    849         }
    850 
    851         if ((SubString2) &&
    852             (SubString2 < SubString1))
    853         {
    854             /* Find end of the escape block starting at "Substring2" */
    855 
    856             SubString2 = strstr (SubString2, AS_STOP_IGNORE);
    857             if (!SubString2)
    858             {
    859                 /* Didn't find terminator */
    860 
    861                 return (ReplaceCount);
    862             }
    863 
    864             /* Move buffer to end of escape block and continue */
    865 
    866             SubBuffer = SubString2;
    867         }
    868 
    869         /* Do the actual replace if the target was found */
    870 
    871         else
    872         {
    873             if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD)
    874             {
    875                 if (!AsMatchExactWord (SubString1, TargetLength))
    876                 {
    877                     SubBuffer = SubString1 + 1;
    878                     continue;
    879                 }
    880             }
    881 
    882             SubBuffer = AsReplaceData (SubString1, TargetLength,
    883                 Replacement, ReplacementLength);
    884 
    885             if ((Type & EXTRA_INDENT_C) &&
    886                 (!Gbl_StructDefs))
    887             {
    888                 SubBuffer = AsInsertData (SubBuffer, "        ", 8);
    889             }
    890 
    891             ReplaceCount++;
    892         }
    893     }
    894 
    895     return (ReplaceCount);
    896 }
    897 
    898 
    899 /******************************************************************************
    900  *
    901  * FUNCTION:    AsConvertToLineFeeds
    902  *
    903  * DESCRIPTION: Convert all CR/LF pairs to LF only.
    904  *
    905  ******************************************************************************/
    906 
    907 void
    908 AsConvertToLineFeeds (
    909     char                    *Buffer)
    910 {
    911     char                    *SubString;
    912     char                    *SubBuffer;
    913 
    914 
    915     SubBuffer = Buffer;
    916     SubString = Buffer;
    917 
    918     while (SubString)
    919     {
    920         /* Find the target string */
    921 
    922         SubString = strstr (SubBuffer, "\r\n");
    923         if (!SubString)
    924         {
    925             return;
    926         }
    927 
    928         SubBuffer = AsReplaceData (SubString, 1, NULL, 0);
    929     }
    930 }
    931 
    932 
    933 /******************************************************************************
    934  *
    935  * FUNCTION:    AsInsertCarriageReturns
    936  *
    937  * DESCRIPTION: Convert lone LFs to CR/LF pairs.
    938  *
    939  ******************************************************************************/
    940 
    941 void
    942 AsInsertCarriageReturns (
    943     char                    *Buffer)
    944 {
    945     char                    *SubString;
    946     char                    *SubBuffer;
    947 
    948 
    949     SubBuffer = Buffer;
    950     SubString = Buffer;
    951 
    952     while (SubString)
    953     {
    954         /* Find the target string */
    955 
    956         SubString = strstr (SubBuffer, "\n");
    957         if (!SubString)
    958         {
    959             return;
    960         }
    961 
    962         SubBuffer = AsInsertData (SubString, "\r", 1);
    963         SubBuffer += 1;
    964     }
    965 }
    966 
    967 
    968 /******************************************************************************
    969  *
    970  * FUNCTION:    AsBracesOnSameLine
    971  *
    972  * DESCRIPTION: Move opening braces up to the same line as an if, for, else,
    973  *              or while statement (leave function opening brace on separate
    974  *              line).
    975  *
    976  ******************************************************************************/
    977 
    978 void
    979 AsBracesOnSameLine (
    980     char                    *Buffer)
    981 {
    982     char                    *SubBuffer = Buffer;
    983     char                    *Beginning;
    984     char                    *StartOfThisLine;
    985     char                    *Next;
    986     BOOLEAN                 BlockBegin = TRUE;
    987 
    988 
    989     while (*SubBuffer)
    990     {
    991         /* Ignore comments */
    992 
    993         if ((SubBuffer[0] == '/') &&
    994             (SubBuffer[1] == '*'))
    995         {
    996             SubBuffer = strstr (SubBuffer, "*/");
    997             if (!SubBuffer)
    998             {
    999                 return;
   1000             }
   1001 
   1002             SubBuffer += 2;
   1003             continue;
   1004         }
   1005 
   1006         /* Ignore quoted strings */
   1007 
   1008         if (*SubBuffer == '\"')
   1009         {
   1010             SubBuffer++;
   1011             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
   1012             if (!SubBuffer)
   1013             {
   1014                 return;
   1015             }
   1016         }
   1017 
   1018         if (!strncmp ("\n}", SubBuffer, 2))
   1019         {
   1020             /*
   1021              * A newline followed by a closing brace closes a function
   1022              * or struct or initializer block
   1023              */
   1024             BlockBegin = TRUE;
   1025         }
   1026 
   1027         /*
   1028          * Move every standalone brace up to the previous line
   1029          * Check for digit will ignore initializer lists surrounded by braces.
   1030          * This will work until we we need more complex detection.
   1031          */
   1032         if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1]))
   1033         {
   1034             if (BlockBegin)
   1035             {
   1036                 BlockBegin = FALSE;
   1037             }
   1038             else
   1039             {
   1040                 /*
   1041                  * Backup to previous non-whitespace
   1042                  */
   1043                 Beginning = SubBuffer - 1;
   1044                 while ((*Beginning == ' ')   ||
   1045                        (*Beginning == '\n'))
   1046                 {
   1047                     Beginning--;
   1048                 }
   1049 
   1050                 StartOfThisLine = Beginning;
   1051                 while (*StartOfThisLine != '\n')
   1052                 {
   1053                     StartOfThisLine--;
   1054                 }
   1055 
   1056                 /*
   1057                  * Move the brace up to the previous line, UNLESS:
   1058                  *
   1059                  * 1) There is a conditional compile on the line (starts with '#')
   1060                  * 2) Previous line ends with an '=' (Start of initializer block)
   1061                  * 3) Previous line ends with a comma (part of an init list)
   1062                  * 4) Previous line ends with a backslash (part of a macro)
   1063                  */
   1064                 if ((StartOfThisLine[1] != '#') &&
   1065                     (*Beginning != '\\') &&
   1066                     (*Beginning != '/') &&
   1067                     (*Beginning != '{') &&
   1068                     (*Beginning != '=') &&
   1069                     (*Beginning != ','))
   1070                 {
   1071                     Beginning++;
   1072                     SubBuffer++;
   1073 
   1074                     Gbl_MadeChanges = TRUE;
   1075 
   1076 #ifdef ADD_EXTRA_WHITESPACE
   1077                     AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
   1078 #else
   1079                     /* Find non-whitespace start of next line */
   1080 
   1081                     Next = SubBuffer + 1;
   1082                     while ((*Next == ' ')   ||
   1083                            (*Next == '\t'))
   1084                     {
   1085                         Next++;
   1086                     }
   1087 
   1088                     /* Find non-whitespace start of this line */
   1089 
   1090                     StartOfThisLine++;
   1091                     while ((*StartOfThisLine == ' ')   ||
   1092                            (*StartOfThisLine == '\t'))
   1093                     {
   1094                         StartOfThisLine++;
   1095                     }
   1096 
   1097                     /*
   1098                      * Must be a single-line comment to need more whitespace
   1099                      * Even then, we don't need more if the previous statement
   1100                      * is an "else".
   1101                      */
   1102                     if ((Next[0] == '/')  &&
   1103                         (Next[1] == '*')  &&
   1104                         (Next[2] != '\n') &&
   1105 
   1106                         (!strncmp (StartOfThisLine, "else if", 7)     ||
   1107                          !strncmp (StartOfThisLine, "else while", 10) ||
   1108                           strncmp (StartOfThisLine, "else", 4)))
   1109                     {
   1110                         AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
   1111                     }
   1112                     else
   1113                     {
   1114                         AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2);
   1115                     }
   1116 #endif
   1117                 }
   1118             }
   1119         }
   1120 
   1121         SubBuffer++;
   1122     }
   1123 }
   1124 
   1125 
   1126 /******************************************************************************
   1127  *
   1128  * FUNCTION:    AsTabify4
   1129  *
   1130  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
   1131  *              preserved.
   1132  *
   1133  ******************************************************************************/
   1134 
   1135 void
   1136 AsTabify4 (
   1137     char                    *Buffer)
   1138 {
   1139     char                    *SubBuffer = Buffer;
   1140     char                    *NewSubBuffer;
   1141     UINT32                  SpaceCount = 0;
   1142     UINT32                  Column = 0;
   1143 
   1144 
   1145     while (*SubBuffer)
   1146     {
   1147         if (*SubBuffer == '\n')
   1148         {
   1149             Column = 0;
   1150         }
   1151         else
   1152         {
   1153             Column++;
   1154         }
   1155 
   1156         /* Ignore comments */
   1157 
   1158         if ((SubBuffer[0] == '/') &&
   1159             (SubBuffer[1] == '*'))
   1160         {
   1161             SubBuffer = strstr (SubBuffer, "*/");
   1162             if (!SubBuffer)
   1163             {
   1164                 return;
   1165             }
   1166 
   1167             SubBuffer += 2;
   1168             continue;
   1169         }
   1170 
   1171         /* Ignore quoted strings */
   1172 
   1173         if (*SubBuffer == '\"')
   1174         {
   1175             SubBuffer++;
   1176             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
   1177             if (!SubBuffer)
   1178             {
   1179                 return;
   1180             }
   1181             SpaceCount = 0;
   1182         }
   1183 
   1184         if (*SubBuffer == ' ')
   1185         {
   1186             SpaceCount++;
   1187 
   1188             if (SpaceCount >= 4)
   1189             {
   1190                 SpaceCount = 0;
   1191 
   1192                 NewSubBuffer = (SubBuffer + 1) - 4;
   1193                 *NewSubBuffer = '\t';
   1194                 NewSubBuffer++;
   1195 
   1196                 /* Remove the spaces */
   1197 
   1198                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1);
   1199             }
   1200 
   1201             if ((Column % 4) == 0)
   1202             {
   1203                 SpaceCount = 0;
   1204             }
   1205         }
   1206         else
   1207         {
   1208             SpaceCount = 0;
   1209         }
   1210 
   1211         SubBuffer++;
   1212     }
   1213 }
   1214 
   1215 
   1216 /******************************************************************************
   1217  *
   1218  * FUNCTION:    AsTabify8
   1219  *
   1220  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
   1221  *              preserved.
   1222  *
   1223  ******************************************************************************/
   1224 
   1225 void
   1226 AsTabify8 (
   1227     char                    *Buffer)
   1228 {
   1229     char                    *SubBuffer = Buffer;
   1230     char                    *NewSubBuffer;
   1231     char                    *CommentEnd = NULL;
   1232     UINT32                  SpaceCount = 0;
   1233     UINT32                  TabCount = 0;
   1234     UINT32                  LastLineTabCount = 0;
   1235     UINT32                  LastLineColumnStart = 0;
   1236     UINT32                  ThisColumnStart = 0;
   1237     UINT32                  ThisTabCount =  0;
   1238     char                    *FirstNonBlank = NULL;
   1239 
   1240 
   1241     while (*SubBuffer)
   1242     {
   1243         if (*SubBuffer == '\n')
   1244         {
   1245             /* This is a standalone blank line */
   1246 
   1247             FirstNonBlank = NULL;
   1248             SpaceCount = 0;
   1249             TabCount = 0;
   1250             SubBuffer++;
   1251             continue;
   1252         }
   1253 
   1254         if (!FirstNonBlank)
   1255         {
   1256             /* Find the first non-blank character on this line */
   1257 
   1258             FirstNonBlank = SubBuffer;
   1259             while (*FirstNonBlank == ' ')
   1260             {
   1261                 FirstNonBlank++;
   1262             }
   1263 
   1264             /*
   1265              * This mechanism limits the difference in tab counts from
   1266              * line to line. It helps avoid the situation where a second
   1267              * continuation line (which was indented correctly for tabs=4) would
   1268              * get indented off the screen if we just blindly converted to tabs.
   1269              */
   1270             ThisColumnStart = FirstNonBlank - SubBuffer;
   1271 
   1272             if (LastLineTabCount == 0)
   1273             {
   1274                 ThisTabCount = 0;
   1275             }
   1276             else if (ThisColumnStart == LastLineColumnStart)
   1277             {
   1278                 ThisTabCount = LastLineTabCount -1;
   1279             }
   1280             else
   1281             {
   1282                 ThisTabCount = LastLineTabCount + 1;
   1283             }
   1284         }
   1285 
   1286         /* Check if we are in a comment */
   1287 
   1288         if ((SubBuffer[0] == '*') &&
   1289             (SubBuffer[1] == '/'))
   1290         {
   1291             SpaceCount = 0;
   1292             SubBuffer += 2;
   1293 
   1294             if (*SubBuffer == '\n')
   1295             {
   1296                 if (TabCount > 0)
   1297                 {
   1298                     LastLineTabCount = TabCount;
   1299                     TabCount = 0;
   1300                 }
   1301 
   1302                 FirstNonBlank = NULL;
   1303                 LastLineColumnStart = ThisColumnStart;
   1304                 SubBuffer++;
   1305             }
   1306 
   1307             continue;
   1308         }
   1309 
   1310         /* Check for comment open */
   1311 
   1312         if ((SubBuffer[0] == '/') &&
   1313             (SubBuffer[1] == '*'))
   1314         {
   1315             /* Find the end of the comment, it must exist */
   1316 
   1317             CommentEnd = strstr (SubBuffer, "*/");
   1318             if (!CommentEnd)
   1319             {
   1320                 return;
   1321             }
   1322 
   1323             /* Toss the rest of this line or single-line comment */
   1324 
   1325             while ((SubBuffer < CommentEnd) &&
   1326                    (*SubBuffer != '\n'))
   1327             {
   1328                 SubBuffer++;
   1329             }
   1330 
   1331             if (*SubBuffer == '\n')
   1332             {
   1333                 if (TabCount > 0)
   1334                 {
   1335                     LastLineTabCount = TabCount;
   1336                     TabCount = 0;
   1337                 }
   1338 
   1339                 FirstNonBlank = NULL;
   1340                 LastLineColumnStart = ThisColumnStart;
   1341             }
   1342 
   1343             SpaceCount = 0;
   1344             continue;
   1345         }
   1346 
   1347         /* Ignore quoted strings */
   1348 
   1349         if ((!CommentEnd) && (*SubBuffer == '\"'))
   1350         {
   1351             SubBuffer++;
   1352             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
   1353             if (!SubBuffer)
   1354             {
   1355                 return;
   1356             }
   1357 
   1358             SpaceCount = 0;
   1359         }
   1360 
   1361         if (*SubBuffer != ' ')
   1362         {
   1363             /* Not a space, skip to end of line */
   1364 
   1365             SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
   1366             if (!SubBuffer)
   1367             {
   1368                 return;
   1369             }
   1370             if (TabCount > 0)
   1371             {
   1372                 LastLineTabCount = TabCount;
   1373                 TabCount = 0;
   1374             }
   1375 
   1376             FirstNonBlank = NULL;
   1377             LastLineColumnStart = ThisColumnStart;
   1378             SpaceCount = 0;
   1379         }
   1380         else
   1381         {
   1382             /* Another space */
   1383 
   1384             SpaceCount++;
   1385 
   1386             if (SpaceCount >= 4)
   1387             {
   1388                 /* Replace this group of spaces with a tab character */
   1389 
   1390                 SpaceCount = 0;
   1391 
   1392                 NewSubBuffer = SubBuffer - 3;
   1393 
   1394                 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0)
   1395                 {
   1396                     *NewSubBuffer = '\t';
   1397                     NewSubBuffer++;
   1398                     SubBuffer++;
   1399                     TabCount++;
   1400                 }
   1401 
   1402                 /* Remove the spaces */
   1403 
   1404                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer);
   1405                 continue;
   1406             }
   1407         }
   1408 
   1409         SubBuffer++;
   1410     }
   1411 }
   1412 
   1413 
   1414 /******************************************************************************
   1415  *
   1416  * FUNCTION:    AsCountLines
   1417  *
   1418  * DESCRIPTION: Count the number of lines in the input buffer. Also count
   1419  *              the number of long lines (lines longer than 80 chars).
   1420  *
   1421  ******************************************************************************/
   1422 
   1423 static UINT32
   1424 AsCountLines (
   1425     char                    *Buffer,
   1426     char                    *Filename)
   1427 {
   1428     char                    *SubBuffer = Buffer;
   1429     char                    *EndOfLine;
   1430     UINT32                  LineCount = 0;
   1431     UINT32                  LongLineCount = 0;
   1432 
   1433 
   1434     while (*SubBuffer)
   1435     {
   1436         EndOfLine = AsSkipUntilChar (SubBuffer, '\n');
   1437         if (!EndOfLine)
   1438         {
   1439             Gbl_TotalLines += LineCount;
   1440             return (LineCount);
   1441         }
   1442 
   1443         if ((EndOfLine - SubBuffer) > 80)
   1444         {
   1445             LongLineCount++;
   1446             VERBOSE_PRINT (("long: %.80s\n", SubBuffer));
   1447         }
   1448 
   1449         LineCount++;
   1450         SubBuffer = EndOfLine + 1;
   1451     }
   1452 
   1453     if (LongLineCount)
   1454     {
   1455         VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n",
   1456             LongLineCount, Filename));
   1457 
   1458         Gbl_LongLines += LongLineCount;
   1459     }
   1460 
   1461     Gbl_TotalLines += LineCount;
   1462     return (LineCount);
   1463 }
   1464 
   1465 
   1466 /******************************************************************************
   1467  *
   1468  * FUNCTION:    AsCountTabs
   1469  *
   1470  * DESCRIPTION: Simply count the number of tabs in the input file buffer
   1471  *
   1472  ******************************************************************************/
   1473 
   1474 void
   1475 AsCountTabs (
   1476     char                    *Buffer,
   1477     char                    *Filename)
   1478 {
   1479     UINT32                  i;
   1480     UINT32                  TabCount = 0;
   1481 
   1482 
   1483     for (i = 0; Buffer[i]; i++)
   1484     {
   1485         if (Buffer[i] == '\t')
   1486         {
   1487             TabCount++;
   1488         }
   1489     }
   1490 
   1491     if (TabCount)
   1492     {
   1493         AsPrint ("Tabs found", TabCount, Filename);
   1494         Gbl_Tabs += TabCount;
   1495     }
   1496 
   1497     AsCountLines (Buffer, Filename);
   1498 }
   1499 
   1500 
   1501 /******************************************************************************
   1502  *
   1503  * FUNCTION:    AsCountSourceLines
   1504  *
   1505  * DESCRIPTION: Count the number of C source lines. Defined by 1) not a
   1506  *              comment, and 2) not a blank line.
   1507  *
   1508  ******************************************************************************/
   1509 
   1510 void
   1511 AsCountSourceLines (
   1512     char                    *Buffer,
   1513     char                    *Filename)
   1514 {
   1515     char                    *SubBuffer = Buffer;
   1516     UINT32                  LineCount = 0;
   1517     UINT32                  WhiteCount = 0;
   1518     UINT32                  CommentCount = 0;
   1519 
   1520 
   1521     while (*SubBuffer)
   1522     {
   1523         /* Detect comments (// comments are not used, non-ansii) */
   1524 
   1525         if ((SubBuffer[0] == '/') &&
   1526             (SubBuffer[1] == '*'))
   1527         {
   1528             SubBuffer += 2;
   1529 
   1530             /* First line of multi-line comment is often just whitespace */
   1531 
   1532             if (SubBuffer[0] == '\n')
   1533             {
   1534                 WhiteCount++;
   1535                 SubBuffer++;
   1536             }
   1537             else
   1538             {
   1539                 CommentCount++;
   1540             }
   1541 
   1542             /* Find end of comment */
   1543 
   1544             while (SubBuffer[0] && SubBuffer[1] &&
   1545                 !(((SubBuffer[0] == '*') &&
   1546                     (SubBuffer[1] == '/'))))
   1547             {
   1548                 if (SubBuffer[0] == '\n')
   1549                 {
   1550                     CommentCount++;
   1551                 }
   1552 
   1553                 SubBuffer++;
   1554             }
   1555         }
   1556 
   1557         /* A linefeed followed by a non-linefeed is a valid source line */
   1558 
   1559         else if ((SubBuffer[0] == '\n') &&
   1560                  (SubBuffer[1] != '\n'))
   1561         {
   1562             LineCount++;
   1563         }
   1564 
   1565         /* Two back-to-back linefeeds indicate a whitespace line */
   1566 
   1567         else if ((SubBuffer[0] == '\n') &&
   1568                  (SubBuffer[1] == '\n'))
   1569         {
   1570             WhiteCount++;
   1571         }
   1572 
   1573         SubBuffer++;
   1574     }
   1575 
   1576     /* Adjust comment count for legal header */
   1577 
   1578     if (Gbl_HeaderSize < CommentCount)
   1579     {
   1580         CommentCount -= Gbl_HeaderSize;
   1581         Gbl_HeaderLines += Gbl_HeaderSize;
   1582     }
   1583 
   1584     Gbl_SourceLines += LineCount;
   1585     Gbl_WhiteLines += WhiteCount;
   1586     Gbl_CommentLines += CommentCount;
   1587 
   1588     VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n",
   1589         CommentCount, WhiteCount, LineCount,
   1590         LineCount + WhiteCount + CommentCount, Filename));
   1591 }
   1592 
   1593 
   1594 /******************************************************************************
   1595  *
   1596  * FUNCTION:    AsInsertPrefix
   1597  *
   1598  * DESCRIPTION: Insert struct or union prefixes
   1599  *
   1600  ******************************************************************************/
   1601 
   1602 void
   1603 AsInsertPrefix (
   1604     char                    *Buffer,
   1605     char                    *Keyword,
   1606     UINT8                   Type)
   1607 {
   1608     char                    *SubString;
   1609     char                    *SubBuffer;
   1610     char                    *EndKeyword;
   1611     int                     InsertLength;
   1612     char                    *InsertString;
   1613     int                     TrailingSpaces;
   1614     char                    LowerKeyword[128];
   1615     int                     KeywordLength;
   1616     char                    *LineStart;
   1617     BOOLEAN                 FoundPrefix;
   1618 
   1619 
   1620     switch (Type)
   1621     {
   1622     case SRC_TYPE_STRUCT:
   1623 
   1624         InsertString = "struct ";
   1625         break;
   1626 
   1627     case SRC_TYPE_UNION:
   1628 
   1629         InsertString = "union ";
   1630         break;
   1631 
   1632     default:
   1633 
   1634         return;
   1635     }
   1636 
   1637     strcpy (LowerKeyword, Keyword);
   1638     AcpiUtStrlwr (LowerKeyword);
   1639 
   1640     SubBuffer = Buffer;
   1641     SubString = Buffer;
   1642     InsertLength = strlen (InsertString);
   1643     KeywordLength = strlen (Keyword);
   1644 
   1645 
   1646     while (SubString)
   1647     {
   1648         /* Find an instance of the keyword */
   1649 
   1650         SubString = strstr (SubBuffer, LowerKeyword);
   1651         if (!SubString)
   1652         {
   1653             return;
   1654         }
   1655 
   1656         SubBuffer = SubString;
   1657 
   1658         /* Must be standalone word, not a substring */
   1659 
   1660         if (AsMatchExactWord (SubString, KeywordLength))
   1661         {
   1662             /* Make sure the keyword isn't already prefixed with the insert */
   1663 
   1664             /* We find the beginning of the line and try to find the InsertString
   1665              * from LineStart up to SubBuffer (our keyword). If it's not there,
   1666              * we assume it doesn't have a prefix; this is a limitation, as having
   1667              * a keyword on another line is absolutely valid C.
   1668              */
   1669 
   1670             LineStart = SubString;
   1671             FoundPrefix = FALSE;
   1672 
   1673             /* Find the start of the line */
   1674 
   1675             while (LineStart > Buffer)
   1676             {
   1677                 if (*LineStart == '\n')
   1678                 {
   1679                     LineStart++;
   1680                     break;
   1681                 }
   1682 
   1683                 LineStart--;
   1684             }
   1685 
   1686             /* Try to find InsertString from the start of the line up to SubBuffer */
   1687             /* Note that this algorithm is a bit naive. */
   1688 
   1689             while (SubBuffer > LineStart)
   1690             {
   1691                 if (*LineStart != *InsertString)
   1692                 {
   1693                     LineStart++;
   1694                     continue;
   1695                 }
   1696 
   1697                 if (strncmp (LineStart++, InsertString, InsertLength))
   1698                 {
   1699                     continue;
   1700                 }
   1701 
   1702                 FoundPrefix = TRUE;
   1703                 LineStart += InsertLength - 1;
   1704 
   1705                 /* Now check if there's non-whitespace between InsertString and SubBuffer, as that
   1706                  * means it's not a valid prefix in this case. */
   1707 
   1708                 while (LineStart != SubBuffer)
   1709                 {
   1710                     if (!strchr (" \t\r\n", *LineStart))
   1711                     {
   1712                         /* We found non-whitespace while traversing up to SubBuffer,
   1713                          * so this isn't a prefix.
   1714                          */
   1715                         FoundPrefix = FALSE;
   1716                         break;
   1717                     }
   1718 
   1719                     LineStart++;
   1720                 }
   1721             }
   1722 
   1723             if (FoundPrefix)
   1724             {
   1725                 /* Add spaces if not already at the end-of-line */
   1726 
   1727                 if (*(SubBuffer + KeywordLength) != '\n')
   1728                 {
   1729                     /* Already present, add spaces after to align structure members */
   1730 
   1731 #if 0
   1732 /* ONLY FOR C FILES */
   1733                     AsInsertData (SubBuffer + KeywordLength, "        ", 8);
   1734 #endif
   1735                 }
   1736                 goto Next;
   1737             }
   1738 
   1739             /* Make sure the keyword isn't at the end of a struct/union */
   1740             /* Note: This code depends on a single space after the brace */
   1741 
   1742             if (*(SubString - 2) == '}')
   1743             {
   1744                 goto Next;
   1745             }
   1746 
   1747             /* Prefix the keyword with the insert string */
   1748 
   1749             Gbl_MadeChanges = TRUE;
   1750 
   1751             /* Is there room for insertion */
   1752 
   1753             EndKeyword = SubString + strlen (LowerKeyword);
   1754 
   1755             TrailingSpaces = 0;
   1756             while (EndKeyword[TrailingSpaces] == ' ')
   1757             {
   1758                 TrailingSpaces++;
   1759             }
   1760 
   1761             /*
   1762              * Use "if (TrailingSpaces > 1)" if we want to ignore casts
   1763              */
   1764             SubBuffer = SubString + InsertLength;
   1765 
   1766             if (TrailingSpaces > InsertLength)
   1767             {
   1768                 /* Insert the keyword */
   1769 
   1770                 memmove (SubBuffer, SubString, KeywordLength);
   1771 
   1772                 /* Insert the keyword */
   1773 
   1774                 memmove (SubString, InsertString, InsertLength);
   1775             }
   1776             else
   1777             {
   1778                 AsInsertData (SubString, InsertString, InsertLength);
   1779             }
   1780         }
   1781 
   1782 Next:
   1783         SubBuffer += KeywordLength;
   1784     }
   1785 }
   1786 
   1787 #ifdef ACPI_FUTURE_IMPLEMENTATION
   1788 /******************************************************************************
   1789  *
   1790  * FUNCTION:    AsTrimComments
   1791  *
   1792  * DESCRIPTION: Finds 3-line comments with only a single line of text
   1793  *
   1794  ******************************************************************************/
   1795 
   1796 void
   1797 AsTrimComments (
   1798     char                    *Buffer,
   1799     char                    *Filename)
   1800 {
   1801     char                    *SubBuffer = Buffer;
   1802     char                    *Ptr1;
   1803     char                    *Ptr2;
   1804     UINT32                  LineCount;
   1805     UINT32                  ShortCommentCount = 0;
   1806 
   1807 
   1808     while (1)
   1809     {
   1810         /* Find comment open, within procedure level */
   1811 
   1812         SubBuffer = strstr (SubBuffer, "    /*");
   1813         if (!SubBuffer)
   1814         {
   1815             goto Exit;
   1816         }
   1817 
   1818         /* Find comment terminator */
   1819 
   1820         Ptr1 = strstr (SubBuffer, "*/");
   1821         if (!Ptr1)
   1822         {
   1823             goto Exit;
   1824         }
   1825 
   1826         /* Find next EOL (from original buffer) */
   1827 
   1828         Ptr2 = strstr (SubBuffer, "\n");
   1829         if (!Ptr2)
   1830         {
   1831             goto Exit;
   1832         }
   1833 
   1834         /* Ignore one-line comments */
   1835 
   1836         if (Ptr1 < Ptr2)
   1837         {
   1838             /* Normal comment, ignore and continue; */
   1839 
   1840             SubBuffer = Ptr2;
   1841             continue;
   1842         }
   1843 
   1844         /* Examine multi-line comment */
   1845 
   1846         LineCount = 1;
   1847         while (Ptr1 > Ptr2)
   1848         {
   1849             /* Find next EOL */
   1850 
   1851             Ptr2++;
   1852             Ptr2 = strstr (Ptr2, "\n");
   1853             if (!Ptr2)
   1854             {
   1855                 goto Exit;
   1856             }
   1857 
   1858             LineCount++;
   1859         }
   1860 
   1861         SubBuffer = Ptr1;
   1862 
   1863         if (LineCount <= 3)
   1864         {
   1865             ShortCommentCount++;
   1866         }
   1867     }
   1868 
   1869 
   1870 Exit:
   1871 
   1872     if (ShortCommentCount)
   1873     {
   1874         AsPrint ("Short Comments found", ShortCommentCount, Filename);
   1875     }
   1876 }
   1877 #endif
   1878 
   1879 #ifdef ACPI_UNUSED_FUNCTIONS
   1880 /******************************************************************************
   1881  *
   1882  * FUNCTION:    AsCheckAndSkipLiterals
   1883  *
   1884  * DESCRIPTION: Generic routine to skip comments and quoted string literals.
   1885  *              Keeps a line count.
   1886  *
   1887  ******************************************************************************/
   1888 
   1889 static char *
   1890 AsCheckAndSkipLiterals (
   1891     char                    *Buffer,
   1892     UINT32                  *TotalLines);
   1893 
   1894 
   1895 static char *
   1896 AsCheckAndSkipLiterals (
   1897     char                    *Buffer,
   1898     UINT32                  *TotalLines)
   1899 {
   1900     UINT32                  NewLines = 0;
   1901     char                    *SubBuffer = Buffer;
   1902     char                    *LiteralEnd;
   1903 
   1904 
   1905     /* Ignore comments */
   1906 
   1907     if ((SubBuffer[0] == '/') &&
   1908         (SubBuffer[1] == '*'))
   1909     {
   1910         LiteralEnd = strstr (SubBuffer, "*/");
   1911         SubBuffer += 2;     /* Get past comment opening */
   1912 
   1913         if (!LiteralEnd)
   1914         {
   1915             return (SubBuffer);
   1916         }
   1917 
   1918         while (SubBuffer < LiteralEnd)
   1919         {
   1920             if (*SubBuffer == '\n')
   1921             {
   1922                 NewLines++;
   1923             }
   1924 
   1925             SubBuffer++;
   1926         }
   1927 
   1928         SubBuffer += 2;     /* Get past comment close */
   1929     }
   1930 
   1931     /* Ignore quoted strings */
   1932 
   1933     else if (*SubBuffer == '\"')
   1934     {
   1935         SubBuffer++;
   1936         LiteralEnd = AsSkipPastChar (SubBuffer, '\"');
   1937         if (!LiteralEnd)
   1938         {
   1939             return (SubBuffer);
   1940         }
   1941     }
   1942 
   1943     if (TotalLines)
   1944     {
   1945         (*TotalLines) += NewLines;
   1946     }
   1947     return (SubBuffer);
   1948 }
   1949 #endif
   1950