1 /******************************************************************************
   2  *
   3  * Module Name: asconvrt - Source conversion code
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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 char *
  49 AsCheckAndSkipLiterals (
  50     char                    *Buffer,
  51     UINT32                  *TotalLines);
  52 
  53 UINT32
  54 AsCountLines (
  55     char                    *Buffer,
  56     char                    *Filename);
  57 
  58 /* Opening signature of the Intel legal header */
  59 
  60 char        *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice";
  61 
  62 
  63 /******************************************************************************
  64  *
  65  * FUNCTION:    AsRemoveExtraLines
  66  *
  67  * DESCRIPTION: Remove all extra lines at the start and end of the file.
  68  *
  69  ******************************************************************************/
  70 
  71 void
  72 AsRemoveExtraLines (
  73     char                    *FileBuffer,
  74     char                    *Filename)
  75 {
  76     char                    *FileEnd;
  77     int                     Length;
  78 
  79 
  80     /* Remove any extra lines at the start of the file */
  81 
  82     while (*FileBuffer == '\n')
  83     {
  84         printf ("Removing extra line at start of file: %s\n", Filename);
  85         AsRemoveData (FileBuffer, FileBuffer + 1);
  86     }
  87 
  88     /* Remove any extra lines at the end of the file */
  89 
  90     Length = strlen (FileBuffer);
  91     FileEnd = FileBuffer + (Length - 2);
  92 
  93     while (*FileEnd == '\n')
  94     {
  95         printf ("Removing extra line at end of file: %s\n", Filename);
  96         AsRemoveData (FileEnd, FileEnd + 1);
  97         FileEnd--;
  98     }
  99 }
 100 
 101 
 102 /******************************************************************************
 103  *
 104  * FUNCTION:    AsRemoveSpacesAfterPeriod
 105  *
 106  * DESCRIPTION: Remove an extra space after a period.
 107  *
 108  ******************************************************************************/
 109 
 110 void
 111 AsRemoveSpacesAfterPeriod (
 112     char                    *FileBuffer,
 113     char                    *Filename)
 114 {
 115     int                     ReplaceCount = 0;
 116     char                    *Possible;
 117 
 118 
 119     Possible = FileBuffer;
 120     while (Possible)
 121     {
 122         Possible = strstr (Possible, ".  ");
 123         if (Possible)
 124         {
 125             if ((*(Possible -1) == '.')  ||
 126                 (*(Possible -1) == '\"') ||
 127                 (*(Possible -1) == '\n'))
 128             {
 129                 Possible += 3;
 130                 continue;
 131             }
 132 
 133             Possible = AsReplaceData (Possible, 3, ". ", 2);
 134             ReplaceCount++;
 135         }
 136     }
 137 
 138     if (ReplaceCount)
 139     {
 140         printf ("Removed %d extra blanks after a period: %s\n",
 141             ReplaceCount, Filename);
 142     }
 143 }
 144 
 145 
 146 /******************************************************************************
 147  *
 148  * FUNCTION:    AsMatchExactWord
 149  *
 150  * DESCRIPTION: Check previous and next characters for whitespace
 151  *
 152  ******************************************************************************/
 153 
 154 BOOLEAN
 155 AsMatchExactWord (
 156     char                    *Word,
 157     UINT32                  WordLength)
 158 {
 159     char                    NextChar;
 160     char                    PrevChar;
 161 
 162 
 163     NextChar = Word[WordLength];
 164     PrevChar = * (Word -1);
 165 
 166     if (isalnum ((int) NextChar) ||
 167         (NextChar == '_')  ||
 168         isalnum ((int) PrevChar) ||
 169         (PrevChar == '_'))
 170     {
 171         return (FALSE);
 172     }
 173 
 174     return (TRUE);
 175 }
 176 
 177 
 178 /******************************************************************************
 179  *
 180  * FUNCTION:    AsPrint
 181  *
 182  * DESCRIPTION: Common formatted print
 183  *
 184  ******************************************************************************/
 185 
 186 void
 187 AsPrint (
 188     char                    *Message,
 189     UINT32                  Count,
 190     char                    *Filename)
 191 {
 192 
 193     if (Gbl_QuietMode)
 194     {
 195         return;
 196     }
 197 
 198     printf ("-- %4u %28.28s : %s\n", Count, Message, Filename);
 199 }
 200 
 201 
 202 /******************************************************************************
 203  *
 204  * FUNCTION:    AsCheckAndSkipLiterals
 205  *
 206  * DESCRIPTION: Generic routine to skip comments and quoted string literals.
 207  *              Keeps a line count.
 208  *
 209  ******************************************************************************/
 210 
 211 char *
 212 AsCheckAndSkipLiterals (
 213     char                    *Buffer,
 214     UINT32                  *TotalLines)
 215 {
 216     UINT32                  NewLines = 0;
 217     char                    *SubBuffer = Buffer;
 218     char                    *LiteralEnd;
 219 
 220 
 221     /* Ignore comments */
 222 
 223     if ((SubBuffer[0] == '/') &&
 224         (SubBuffer[1] == '*'))
 225     {
 226         LiteralEnd = strstr (SubBuffer, "*/");
 227         SubBuffer += 2;     /* Get past comment opening */
 228 
 229         if (!LiteralEnd)
 230         {
 231             return (SubBuffer);
 232         }
 233 
 234         while (SubBuffer < LiteralEnd)
 235         {
 236             if (*SubBuffer == '\n')
 237             {
 238                 NewLines++;
 239             }
 240 
 241             SubBuffer++;
 242         }
 243 
 244         SubBuffer += 2;     /* Get past comment close */
 245     }
 246 
 247     /* Ignore quoted strings */
 248 
 249     else if (*SubBuffer == '\"')
 250     {
 251         SubBuffer++;
 252         LiteralEnd = AsSkipPastChar (SubBuffer, '\"');
 253         if (!LiteralEnd)
 254         {
 255             return (SubBuffer);
 256         }
 257     }
 258 
 259     if (TotalLines)
 260     {
 261         (*TotalLines) += NewLines;
 262     }
 263     return (SubBuffer);
 264 }
 265 
 266 
 267 /******************************************************************************
 268  *
 269  * FUNCTION:    AsAsCheckForBraces
 270  *
 271  * DESCRIPTION: Check for an open brace after each if statement
 272  *
 273  ******************************************************************************/
 274 
 275 void
 276 AsCheckForBraces (
 277     char                    *Buffer,
 278     char                    *Filename)
 279 {
 280     char                    *SubBuffer = Buffer;
 281     char                    *NextBrace;
 282     char                    *NextSemicolon;
 283     char                    *NextIf;
 284     UINT32                  TotalLines = 1;
 285 
 286 
 287     while (*SubBuffer)
 288     {
 289 
 290         SubBuffer = AsCheckAndSkipLiterals (SubBuffer, &TotalLines);
 291 
 292         if (*SubBuffer == '\n')
 293         {
 294             TotalLines++;
 295         }
 296         else if (!(strncmp (" if", SubBuffer, 3)))
 297         {
 298             SubBuffer += 2;
 299             NextBrace = strstr (SubBuffer, "{");
 300             NextSemicolon = strstr (SubBuffer, ";");
 301             NextIf = strstr (SubBuffer, " if");
 302 
 303             if ((!NextBrace) ||
 304                (NextSemicolon && (NextBrace > NextSemicolon)) ||
 305                (NextIf && (NextBrace > NextIf)))
 306             {
 307                 Gbl_MissingBraces++;
 308 
 309                 if (!Gbl_QuietMode)
 310                 {
 311                     printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename);
 312                 }
 313             }
 314         }
 315         else if (!(strncmp (" else if", SubBuffer, 8)))
 316         {
 317             SubBuffer += 7;
 318             NextBrace = strstr (SubBuffer, "{");
 319             NextSemicolon = strstr (SubBuffer, ";");
 320             NextIf = strstr (SubBuffer, " if");
 321 
 322             if ((!NextBrace) ||
 323                (NextSemicolon && (NextBrace > NextSemicolon)) ||
 324                (NextIf && (NextBrace > NextIf)))
 325             {
 326                 Gbl_MissingBraces++;
 327 
 328                 if (!Gbl_QuietMode)
 329                 {
 330                     printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename);
 331                 }
 332             }
 333         }
 334         else if (!(strncmp (" else", SubBuffer, 5)))
 335         {
 336             SubBuffer += 4;
 337             NextBrace = strstr (SubBuffer, "{");
 338             NextSemicolon = strstr (SubBuffer, ";");
 339             NextIf = strstr (SubBuffer, " if");
 340 
 341             if ((!NextBrace) ||
 342                (NextSemicolon && (NextBrace > NextSemicolon)) ||
 343                (NextIf && (NextBrace > NextIf)))
 344             {
 345                 Gbl_MissingBraces++;
 346 
 347                 if (!Gbl_QuietMode)
 348                 {
 349                     printf ("Missing braces for <else>, line %u: %s\n", TotalLines, Filename);
 350                 }
 351             }
 352         }
 353 
 354         SubBuffer++;
 355     }
 356 }
 357 
 358 
 359 /******************************************************************************
 360  *
 361  * FUNCTION:    AsTrimLines
 362  *
 363  * DESCRIPTION: Remove extra blanks from the end of source lines. Does not
 364  *              check for tabs.
 365  *
 366  ******************************************************************************/
 367 
 368 void
 369 AsTrimLines (
 370     char                    *Buffer,
 371     char                    *Filename)
 372 {
 373     char                    *SubBuffer = Buffer;
 374     char                    *StartWhiteSpace = NULL;
 375     UINT32                  SpaceCount = 0;
 376 
 377 
 378     while (*SubBuffer)
 379     {
 380         while (*SubBuffer != '\n')
 381         {
 382             if (!*SubBuffer)
 383             {
 384                 goto Exit;
 385             }
 386 
 387             if (*SubBuffer == ' ')
 388             {
 389                 if (!StartWhiteSpace)
 390                 {
 391                     StartWhiteSpace = SubBuffer;
 392                 }
 393             }
 394             else
 395             {
 396                 StartWhiteSpace = NULL;
 397             }
 398 
 399             SubBuffer++;
 400         }
 401 
 402         if (StartWhiteSpace)
 403         {
 404             SpaceCount += (SubBuffer - StartWhiteSpace);
 405 
 406             /* Remove the spaces */
 407 
 408             SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer);
 409             StartWhiteSpace = NULL;
 410         }
 411 
 412         SubBuffer++;
 413     }
 414 
 415 
 416 Exit:
 417     if (SpaceCount)
 418     {
 419         Gbl_MadeChanges = TRUE;
 420         AsPrint ("Extraneous spaces removed", SpaceCount, Filename);
 421     }
 422 }
 423 
 424 
 425 /******************************************************************************
 426  *
 427  * FUNCTION:    AsTrimWhitespace
 428  *
 429  * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines.
 430  *              this can happen during the translation when lines are removed.
 431  *
 432  ******************************************************************************/
 433 
 434 void
 435 AsTrimWhitespace (
 436     char                    *Buffer)
 437 {
 438     int                     ReplaceCount = 1;
 439 
 440 
 441     while (ReplaceCount)
 442     {
 443         ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", REPLACE_SUBSTRINGS, Buffer);
 444     }
 445 }
 446 
 447 
 448 /******************************************************************************
 449  *
 450  * FUNCTION:    AsReplaceHeader
 451  *
 452  * DESCRIPTION: Replace the default Intel legal header with a new header
 453  *
 454  ******************************************************************************/
 455 
 456 void
 457 AsReplaceHeader (
 458     char                    *Buffer,
 459     char                    *NewHeader)
 460 {
 461     char                    *SubBuffer;
 462     char                    *TokenEnd;
 463 
 464 
 465     /* Find the original header */
 466 
 467     SubBuffer = strstr (Buffer, HeaderBegin);
 468     if (!SubBuffer)
 469     {
 470         return;
 471     }
 472 
 473     /* Find the end of the original header */
 474 
 475     TokenEnd = strstr (SubBuffer, "*/");
 476     TokenEnd = AsSkipPastChar (TokenEnd, '\n');
 477 
 478     /* Delete old header, insert new one */
 479 
 480     AsReplaceData (SubBuffer, TokenEnd - SubBuffer, NewHeader, strlen (NewHeader));
 481 }
 482 
 483 
 484 /******************************************************************************
 485  *
 486  * FUNCTION:    AsReplaceString
 487  *
 488  * DESCRIPTION: Replace all instances of a target string with a replacement
 489  *              string. Returns count of the strings replaced.
 490  *
 491  ******************************************************************************/
 492 
 493 int
 494 AsReplaceString (
 495     char                    *Target,
 496     char                    *Replacement,
 497     UINT8                   Type,
 498     char                    *Buffer)
 499 {
 500     char                    *SubString1;
 501     char                    *SubString2;
 502     char                    *SubBuffer;
 503     int                     TargetLength;
 504     int                     ReplacementLength;
 505     int                     ReplaceCount = 0;
 506 
 507 
 508     TargetLength = strlen (Target);
 509     ReplacementLength = strlen (Replacement);
 510 
 511     SubBuffer = Buffer;
 512     SubString1 = Buffer;
 513 
 514     while (SubString1)
 515     {
 516         /* Find the target string */
 517 
 518         SubString1 = strstr (SubBuffer, Target);
 519         if (!SubString1)
 520         {
 521             return (ReplaceCount);
 522         }
 523 
 524         /*
 525          * Check for translation escape string -- means to ignore
 526          * blocks of code while replacing
 527          */
 528         if (Gbl_IgnoreTranslationEscapes)
 529         {
 530             SubString2 = NULL;
 531         }
 532         else
 533         {
 534             SubString2 = strstr (SubBuffer, AS_START_IGNORE);
 535         }
 536 
 537         if ((SubString2) &&
 538             (SubString2 < SubString1))
 539         {
 540             /* Find end of the escape block starting at "Substring2" */
 541 
 542             SubString2 = strstr (SubString2, AS_STOP_IGNORE);
 543             if (!SubString2)
 544             {
 545                 /* Didn't find terminator */
 546 
 547                 return (ReplaceCount);
 548             }
 549 
 550             /* Move buffer to end of escape block and continue */
 551 
 552             SubBuffer = SubString2;
 553         }
 554 
 555         /* Do the actual replace if the target was found */
 556 
 557         else
 558         {
 559             if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD)
 560             {
 561                 if (!AsMatchExactWord (SubString1, TargetLength))
 562                 {
 563                     SubBuffer = SubString1 + 1;
 564                     continue;
 565                 }
 566             }
 567 
 568             SubBuffer = AsReplaceData (SubString1, TargetLength, Replacement, ReplacementLength);
 569 
 570             if ((Type & EXTRA_INDENT_C) &&
 571                 (!Gbl_StructDefs))
 572             {
 573                 SubBuffer = AsInsertData (SubBuffer, "        ", 8);
 574             }
 575 
 576             ReplaceCount++;
 577         }
 578     }
 579 
 580     return (ReplaceCount);
 581 }
 582 
 583 
 584 /******************************************************************************
 585  *
 586  * FUNCTION:    AsConvertToLineFeeds
 587  *
 588  * DESCRIPTION:
 589  *
 590  ******************************************************************************/
 591 
 592 void
 593 AsConvertToLineFeeds (
 594     char                    *Buffer)
 595 {
 596     char                    *SubString;
 597     char                    *SubBuffer;
 598 
 599 
 600     SubBuffer = Buffer;
 601     SubString = Buffer;
 602 
 603     while (SubString)
 604     {
 605         /* Find the target string */
 606 
 607         SubString = strstr (SubBuffer, "\r\n");
 608         if (!SubString)
 609         {
 610             return;
 611         }
 612 
 613         SubBuffer = AsReplaceData (SubString, 1, NULL, 0);
 614     }
 615     return;
 616 }
 617 
 618 
 619 /******************************************************************************
 620  *
 621  * FUNCTION:    AsInsertCarriageReturns
 622  *
 623  * DESCRIPTION:
 624  *
 625  ******************************************************************************/
 626 
 627 void
 628 AsInsertCarriageReturns (
 629     char                    *Buffer)
 630 {
 631     char                    *SubString;
 632     char                    *SubBuffer;
 633 
 634 
 635     SubBuffer = Buffer;
 636     SubString = Buffer;
 637 
 638     while (SubString)
 639     {
 640         /* Find the target string */
 641 
 642         SubString = strstr (SubBuffer, "\n");
 643         if (!SubString)
 644         {
 645             return;
 646         }
 647 
 648         SubBuffer = AsInsertData (SubString, "\r", 1);
 649         SubBuffer += 1;
 650     }
 651     return;
 652 }
 653 
 654 
 655 /******************************************************************************
 656  *
 657  * FUNCTION:    AsBracesOnSameLine
 658  *
 659  * DESCRIPTION: Move opening braces up to the same line as an if, for, else,
 660  *              or while statement (leave function opening brace on separate
 661  *              line).
 662  *
 663  ******************************************************************************/
 664 
 665 void
 666 AsBracesOnSameLine (
 667     char                    *Buffer)
 668 {
 669     char                    *SubBuffer = Buffer;
 670     char                    *Beginning;
 671     char                    *StartOfThisLine;
 672     char                    *Next;
 673     BOOLEAN                 BlockBegin = TRUE;
 674 
 675 
 676     while (*SubBuffer)
 677     {
 678         /* Ignore comments */
 679 
 680         if ((SubBuffer[0] == '/') &&
 681             (SubBuffer[1] == '*'))
 682         {
 683             SubBuffer = strstr (SubBuffer, "*/");
 684             if (!SubBuffer)
 685             {
 686                 return;
 687             }
 688 
 689             SubBuffer += 2;
 690             continue;
 691         }
 692 
 693         /* Ignore quoted strings */
 694 
 695         if (*SubBuffer == '\"')
 696         {
 697             SubBuffer++;
 698             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
 699             if (!SubBuffer)
 700             {
 701                 return;
 702             }
 703         }
 704 
 705         if (!strncmp ("\n}", SubBuffer, 2))
 706         {
 707             /*
 708              * A newline followed by a closing brace closes a function
 709              * or struct or initializer block
 710              */
 711             BlockBegin = TRUE;
 712         }
 713 
 714         /*
 715          * Move every standalone brace up to the previous line
 716          * Check for digit will ignore initializer lists surrounded by braces.
 717          * This will work until we we need more complex detection.
 718          */
 719         if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1]))
 720         {
 721             if (BlockBegin)
 722             {
 723                 BlockBegin = FALSE;
 724             }
 725             else
 726             {
 727                 /*
 728                  * Backup to previous non-whitespace
 729                  */
 730                 Beginning = SubBuffer - 1;
 731                 while ((*Beginning == ' ')   ||
 732                        (*Beginning == '\n'))
 733                 {
 734                     Beginning--;
 735                 }
 736 
 737                 StartOfThisLine = Beginning;
 738                 while (*StartOfThisLine != '\n')
 739                 {
 740                     StartOfThisLine--;
 741                 }
 742 
 743                 /*
 744                  * Move the brace up to the previous line, UNLESS:
 745                  *
 746                  * 1) There is a conditional compile on the line (starts with '#')
 747                  * 2) Previous line ends with an '=' (Start of initializer block)
 748                  * 3) Previous line ends with a comma (part of an init list)
 749                  * 4) Previous line ends with a backslash (part of a macro)
 750                  */
 751                 if ((StartOfThisLine[1] != '#') &&
 752                     (*Beginning != '\\') &&
 753                     (*Beginning != '/') &&
 754                     (*Beginning != '{') &&
 755                     (*Beginning != '=') &&
 756                     (*Beginning != ','))
 757                 {
 758                     Beginning++;
 759                     SubBuffer++;
 760 
 761                     Gbl_MadeChanges = TRUE;
 762 
 763 #ifdef ADD_EXTRA_WHITESPACE
 764                     AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
 765 #else
 766                     /* Find non-whitespace start of next line */
 767 
 768                     Next = SubBuffer + 1;
 769                     while ((*Next == ' ')   ||
 770                            (*Next == '\t'))
 771                     {
 772                         Next++;
 773                     }
 774 
 775                     /* Find non-whitespace start of this line */
 776 
 777                     StartOfThisLine++;
 778                     while ((*StartOfThisLine == ' ')   ||
 779                            (*StartOfThisLine == '\t'))
 780                     {
 781                         StartOfThisLine++;
 782                     }
 783 
 784                     /*
 785                      * Must be a single-line comment to need more whitespace
 786                      * Even then, we don't need more if the previous statement
 787                      * is an "else".
 788                      */
 789                     if ((Next[0] == '/')  &&
 790                         (Next[1] == '*')  &&
 791                         (Next[2] != '\n') &&
 792 
 793                         (!strncmp (StartOfThisLine, "else if", 7)     ||
 794                          !strncmp (StartOfThisLine, "else while", 10) ||
 795                           strncmp (StartOfThisLine, "else", 4)))
 796                     {
 797                         AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
 798                     }
 799                     else
 800                     {
 801                         AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2);
 802                     }
 803 #endif
 804                 }
 805             }
 806         }
 807 
 808         SubBuffer++;
 809     }
 810 }
 811 
 812 
 813 /******************************************************************************
 814  *
 815  * FUNCTION:    AsTabify4
 816  *
 817  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
 818  *              preserved.
 819  *
 820  ******************************************************************************/
 821 
 822 void
 823 AsTabify4 (
 824     char                    *Buffer)
 825 {
 826     char                    *SubBuffer = Buffer;
 827     char                    *NewSubBuffer;
 828     UINT32                  SpaceCount = 0;
 829     UINT32                  Column = 0;
 830 
 831 
 832     while (*SubBuffer)
 833     {
 834         if (*SubBuffer == '\n')
 835         {
 836             Column = 0;
 837         }
 838         else
 839         {
 840             Column++;
 841         }
 842 
 843         /* Ignore comments */
 844 
 845         if ((SubBuffer[0] == '/') &&
 846             (SubBuffer[1] == '*'))
 847         {
 848             SubBuffer = strstr (SubBuffer, "*/");
 849             if (!SubBuffer)
 850             {
 851                 return;
 852             }
 853 
 854             SubBuffer += 2;
 855             continue;
 856         }
 857 
 858         /* Ignore quoted strings */
 859 
 860         if (*SubBuffer == '\"')
 861         {
 862             SubBuffer++;
 863             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
 864             if (!SubBuffer)
 865             {
 866                 return;
 867             }
 868             SpaceCount = 0;
 869         }
 870 
 871         if (*SubBuffer == ' ')
 872         {
 873             SpaceCount++;
 874 
 875             if (SpaceCount >= 4)
 876             {
 877                 SpaceCount = 0;
 878 
 879                 NewSubBuffer = (SubBuffer + 1) - 4;
 880                 *NewSubBuffer = '\t';
 881                 NewSubBuffer++;
 882 
 883                 /* Remove the spaces */
 884 
 885                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1);
 886             }
 887 
 888             if ((Column % 4) == 0)
 889             {
 890                 SpaceCount = 0;
 891             }
 892         }
 893         else
 894         {
 895             SpaceCount = 0;
 896         }
 897 
 898         SubBuffer++;
 899     }
 900 }
 901 
 902 
 903 /******************************************************************************
 904  *
 905  * FUNCTION:    AsTabify8
 906  *
 907  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
 908  *              preserved.
 909  *
 910  ******************************************************************************/
 911 
 912 void
 913 AsTabify8 (
 914     char                    *Buffer)
 915 {
 916     char                    *SubBuffer = Buffer;
 917     char                    *NewSubBuffer;
 918     char                    *CommentEnd = NULL;
 919     UINT32                  SpaceCount = 0;
 920     UINT32                  Column = 0;
 921     UINT32                  TabCount = 0;
 922     UINT32                  LastLineTabCount = 0;
 923     UINT32                  LastLineColumnStart = 0;
 924     UINT32                  ThisColumnStart = 0;
 925     UINT32                  ThisTabCount =  0;
 926     char                    *FirstNonBlank = NULL;
 927 
 928 
 929     while (*SubBuffer)
 930     {
 931         if (*SubBuffer == '\n')
 932         {
 933             /* This is a standalone blank line */
 934 
 935             FirstNonBlank = NULL;
 936             Column = 0;
 937             SpaceCount = 0;
 938             TabCount = 0;
 939             SubBuffer++;
 940             continue;
 941         }
 942 
 943         if (!FirstNonBlank)
 944         {
 945             /* Find the first non-blank character on this line */
 946 
 947             FirstNonBlank = SubBuffer;
 948             while (*FirstNonBlank == ' ')
 949             {
 950                 FirstNonBlank++;
 951             }
 952 
 953             /*
 954              * This mechanism limits the difference in tab counts from
 955              * line to line. It helps avoid the situation where a second
 956              * continuation line (which was indented correctly for tabs=4) would
 957              * get indented off the screen if we just blindly converted to tabs.
 958              */
 959             ThisColumnStart = FirstNonBlank - SubBuffer;
 960 
 961             if (LastLineTabCount == 0)
 962             {
 963                 ThisTabCount = 0;
 964             }
 965             else if (ThisColumnStart == LastLineColumnStart)
 966             {
 967                 ThisTabCount = LastLineTabCount -1;
 968             }
 969             else
 970             {
 971                 ThisTabCount = LastLineTabCount + 1;
 972             }
 973         }
 974 
 975         Column++;
 976 
 977         /* Check if we are in a comment */
 978 
 979         if ((SubBuffer[0] == '*') &&
 980             (SubBuffer[1] == '/'))
 981         {
 982             SpaceCount = 0;
 983             SubBuffer += 2;
 984 
 985             if (*SubBuffer == '\n')
 986             {
 987                 if (TabCount > 0)
 988                 {
 989                     LastLineTabCount = TabCount;
 990                     TabCount = 0;
 991                 }
 992                 FirstNonBlank = NULL;
 993                 LastLineColumnStart = ThisColumnStart;
 994                 SubBuffer++;
 995             }
 996 
 997             continue;
 998         }
 999 
1000         /* Check for comment open */
1001 
1002         if ((SubBuffer[0] == '/') &&
1003             (SubBuffer[1] == '*'))
1004         {
1005             /* Find the end of the comment, it must exist */
1006 
1007             CommentEnd = strstr (SubBuffer, "*/");
1008             if (!CommentEnd)
1009             {
1010                 return;
1011             }
1012 
1013             /* Toss the rest of this line or single-line comment */
1014 
1015             while ((SubBuffer < CommentEnd) &&
1016                    (*SubBuffer != '\n'))
1017             {
1018                 SubBuffer++;
1019             }
1020 
1021             if (*SubBuffer == '\n')
1022             {
1023                 if (TabCount > 0)
1024                 {
1025                     LastLineTabCount = TabCount;
1026                     TabCount = 0;
1027                 }
1028                 FirstNonBlank = NULL;
1029                 LastLineColumnStart = ThisColumnStart;
1030             }
1031 
1032             SpaceCount = 0;
1033             continue;
1034         }
1035 
1036         /* Ignore quoted strings */
1037 
1038         if ((!CommentEnd) && (*SubBuffer == '\"'))
1039         {
1040             SubBuffer++;
1041             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
1042             if (!SubBuffer)
1043             {
1044                 return;
1045             }
1046             SpaceCount = 0;
1047         }
1048 
1049         if (*SubBuffer != ' ')
1050         {
1051             /* Not a space, skip to end of line */
1052 
1053             SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
1054             if (!SubBuffer)
1055             {
1056                 return;
1057             }
1058             if (TabCount > 0)
1059             {
1060                 LastLineTabCount = TabCount;
1061                 TabCount = 0;
1062             }
1063 
1064             FirstNonBlank = NULL;
1065             LastLineColumnStart = ThisColumnStart;
1066             Column = 0;
1067             SpaceCount = 0;
1068         }
1069         else
1070         {
1071             /* Another space */
1072 
1073             SpaceCount++;
1074 
1075             if (SpaceCount >= 4)
1076             {
1077                 /* Replace this group of spaces with a tab character */
1078 
1079                 SpaceCount = 0;
1080 
1081                 NewSubBuffer = SubBuffer - 3;
1082 
1083                 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0)
1084                 {
1085                     *NewSubBuffer = '\t';
1086                     NewSubBuffer++;
1087                     SubBuffer++;
1088                     TabCount++;
1089                 }
1090 
1091                 /* Remove the spaces */
1092 
1093                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer);
1094                 continue;
1095             }
1096         }
1097 
1098         SubBuffer++;
1099     }
1100 }
1101 
1102 
1103 /******************************************************************************
1104  *
1105  * FUNCTION:    AsCountLines
1106  *
1107  * DESCRIPTION: Count the number of lines in the input buffer. Also count
1108  *              the number of long lines (lines longer than 80 chars).
1109  *
1110  ******************************************************************************/
1111 
1112 UINT32
1113 AsCountLines (
1114     char                    *Buffer,
1115     char                    *Filename)
1116 {
1117     char                    *SubBuffer = Buffer;
1118     char                    *EndOfLine;
1119     UINT32                  LineCount = 0;
1120     UINT32                  LongLineCount = 0;
1121 
1122 
1123     while (*SubBuffer)
1124     {
1125         EndOfLine = AsSkipUntilChar (SubBuffer, '\n');
1126         if (!EndOfLine)
1127         {
1128             Gbl_TotalLines += LineCount;
1129             return (LineCount);
1130         }
1131 
1132         if ((EndOfLine - SubBuffer) > 80)
1133         {
1134             LongLineCount++;
1135             VERBOSE_PRINT (("long: %.80s\n", SubBuffer));
1136         }
1137 
1138         LineCount++;
1139         SubBuffer = EndOfLine + 1;
1140     }
1141 
1142     if (LongLineCount)
1143     {
1144         VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n", LongLineCount, Filename));
1145         Gbl_LongLines += LongLineCount;
1146     }
1147 
1148     Gbl_TotalLines += LineCount;
1149     return (LineCount);
1150 }
1151 
1152 
1153 /******************************************************************************
1154  *
1155  * FUNCTION:    AsCountTabs
1156  *
1157  * DESCRIPTION: Simply count the number of tabs in the input file buffer
1158  *
1159  ******************************************************************************/
1160 
1161 void
1162 AsCountTabs (
1163     char                    *Buffer,
1164     char                    *Filename)
1165 {
1166     UINT32                  i;
1167     UINT32                  TabCount = 0;
1168 
1169 
1170     for (i = 0; Buffer[i]; i++)
1171     {
1172         if (Buffer[i] == '\t')
1173         {
1174             TabCount++;
1175         }
1176     }
1177 
1178     if (TabCount)
1179     {
1180         AsPrint ("Tabs found", TabCount, Filename);
1181         Gbl_Tabs += TabCount;
1182     }
1183 
1184     AsCountLines (Buffer, Filename);
1185 }
1186 
1187 
1188 /******************************************************************************
1189  *
1190  * FUNCTION:    AsCountNonAnsiComments
1191  *
1192  * DESCRIPTION: Count the number of "//" comments. This type of comment is
1193  *              non-ANSI C.
1194  *
1195  ******************************************************************************/
1196 
1197 void
1198 AsCountNonAnsiComments (
1199     char                    *Buffer,
1200     char                    *Filename)
1201 {
1202     char                    *SubBuffer = Buffer;
1203     UINT32                  CommentCount = 0;
1204 
1205 
1206     while (SubBuffer)
1207     {
1208         SubBuffer = strstr (SubBuffer, "//");
1209         if (SubBuffer)
1210         {
1211             CommentCount++;
1212             SubBuffer += 2;
1213         }
1214     }
1215 
1216     if (CommentCount)
1217     {
1218         AsPrint ("Non-ANSI Comments found", CommentCount, Filename);
1219         Gbl_NonAnsiComments += CommentCount;
1220     }
1221 }
1222 
1223 
1224 /******************************************************************************
1225  *
1226  * FUNCTION:    AsCountSourceLines
1227  *
1228  * DESCRIPTION: Count the number of C source lines. Defined by 1) not a
1229  *              comment, and 2) not a blank line.
1230  *
1231  ******************************************************************************/
1232 
1233 void
1234 AsCountSourceLines (
1235     char                    *Buffer,
1236     char                    *Filename)
1237 {
1238     char                    *SubBuffer = Buffer;
1239     UINT32                  LineCount = 0;
1240     UINT32                  WhiteCount = 0;
1241     UINT32                  CommentCount = 0;
1242 
1243 
1244     while (*SubBuffer)
1245     {
1246         /* Detect comments (// comments are not used, non-ansii) */
1247 
1248         if ((SubBuffer[0] == '/') &&
1249             (SubBuffer[1] == '*'))
1250         {
1251             SubBuffer += 2;
1252 
1253             /* First line of multi-line comment is often just whitespace */
1254 
1255             if (SubBuffer[0] == '\n')
1256             {
1257                 WhiteCount++;
1258                 SubBuffer++;
1259             }
1260             else
1261             {
1262                 CommentCount++;
1263             }
1264 
1265             /* Find end of comment */
1266 
1267             while (SubBuffer[0] && SubBuffer[1] &&
1268                     !(((SubBuffer[0] == '*') &&
1269                       (SubBuffer[1] == '/'))))
1270             {
1271                 if (SubBuffer[0] == '\n')
1272                 {
1273                     CommentCount++;
1274                 }
1275 
1276                 SubBuffer++;
1277             }
1278         }
1279 
1280         /* A linefeed followed by a non-linefeed is a valid source line */
1281 
1282         else if ((SubBuffer[0] == '\n') &&
1283                  (SubBuffer[1] != '\n'))
1284         {
1285             LineCount++;
1286         }
1287 
1288         /* Two back-to-back linefeeds indicate a whitespace line */
1289 
1290         else if ((SubBuffer[0] == '\n') &&
1291                  (SubBuffer[1] == '\n'))
1292         {
1293             WhiteCount++;
1294         }
1295 
1296         SubBuffer++;
1297     }
1298 
1299     /* Adjust comment count for legal header */
1300 
1301     if (Gbl_HeaderSize < CommentCount)
1302     {
1303         CommentCount -= Gbl_HeaderSize;
1304         Gbl_HeaderLines += Gbl_HeaderSize;
1305     }
1306 
1307     Gbl_SourceLines += LineCount;
1308     Gbl_WhiteLines += WhiteCount;
1309     Gbl_CommentLines += CommentCount;
1310 
1311     VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n",
1312                 CommentCount, WhiteCount, LineCount, LineCount+WhiteCount+CommentCount, Filename));
1313 }
1314 
1315 
1316 /******************************************************************************
1317  *
1318  * FUNCTION:    AsInsertPrefix
1319  *
1320  * DESCRIPTION: Insert struct or union prefixes
1321  *
1322  ******************************************************************************/
1323 
1324 void
1325 AsInsertPrefix (
1326     char                    *Buffer,
1327     char                    *Keyword,
1328     UINT8                   Type)
1329 {
1330     char                    *SubString;
1331     char                    *SubBuffer;
1332     char                    *EndKeyword;
1333     int                     InsertLength;
1334     char                    *InsertString;
1335     int                     TrailingSpaces;
1336     char                    LowerKeyword[128];
1337     int                     KeywordLength;
1338 
1339 
1340     switch (Type)
1341     {
1342     case SRC_TYPE_STRUCT:
1343 
1344         InsertString = "struct ";
1345         break;
1346 
1347     case SRC_TYPE_UNION:
1348 
1349         InsertString = "union ";
1350         break;
1351 
1352     default:
1353 
1354         return;
1355     }
1356 
1357     strcpy (LowerKeyword, Keyword);
1358     AsStrlwr (LowerKeyword);
1359 
1360     SubBuffer = Buffer;
1361     SubString = Buffer;
1362     InsertLength = strlen (InsertString);
1363     KeywordLength = strlen (Keyword);
1364 
1365 
1366     while (SubString)
1367     {
1368         /* Find an instance of the keyword */
1369 
1370         SubString = strstr (SubBuffer, LowerKeyword);
1371         if (!SubString)
1372         {
1373             return;
1374         }
1375 
1376         SubBuffer = SubString;
1377 
1378         /* Must be standalone word, not a substring */
1379 
1380         if (AsMatchExactWord (SubString, KeywordLength))
1381         {
1382             /* Make sure the keyword isn't already prefixed with the insert */
1383 
1384             if (!strncmp (SubString - InsertLength, InsertString, InsertLength))
1385             {
1386                 /* Add spaces if not already at the end-of-line */
1387 
1388                 if (*(SubBuffer + KeywordLength) != '\n')
1389                 {
1390                     /* Already present, add spaces after to align structure members */
1391 
1392 #if 0
1393 /* ONLY FOR C FILES */
1394                     AsInsertData (SubBuffer + KeywordLength, "        ", 8);
1395 #endif
1396                 }
1397                 goto Next;
1398             }
1399 
1400             /* Make sure the keyword isn't at the end of a struct/union */
1401             /* Note: This code depends on a single space after the brace */
1402 
1403             if (*(SubString - 2) == '}')
1404             {
1405                 goto Next;
1406             }
1407 
1408             /* Prefix the keyword with the insert string */
1409 
1410             Gbl_MadeChanges = TRUE;
1411 
1412             /* Is there room for insertion */
1413 
1414             EndKeyword = SubString + strlen (LowerKeyword);
1415 
1416             TrailingSpaces = 0;
1417             while (EndKeyword[TrailingSpaces] == ' ')
1418             {
1419                 TrailingSpaces++;
1420             }
1421 
1422             /*
1423              * Use "if (TrailingSpaces > 1)" if we want to ignore casts
1424              */
1425             SubBuffer = SubString + InsertLength;
1426 
1427             if (TrailingSpaces > InsertLength)
1428             {
1429                 /* Insert the keyword */
1430 
1431                 memmove (SubBuffer, SubString, KeywordLength);
1432 
1433                 /* Insert the keyword */
1434 
1435                 memmove (SubString, InsertString, InsertLength);
1436             }
1437             else
1438             {
1439                 AsInsertData (SubString, InsertString, InsertLength);
1440             }
1441         }
1442 
1443 Next:
1444         SubBuffer += KeywordLength;
1445     }
1446 }
1447 
1448 #ifdef ACPI_FUTURE_IMPLEMENTATION
1449 /******************************************************************************
1450  *
1451  * FUNCTION:    AsTrimComments
1452  *
1453  * DESCRIPTION: Finds 3-line comments with only a single line of text
1454  *
1455  ******************************************************************************/
1456 
1457 void
1458 AsTrimComments (
1459     char                    *Buffer,
1460     char                    *Filename)
1461 {
1462     char                    *SubBuffer = Buffer;
1463     char                    *Ptr1;
1464     char                    *Ptr2;
1465     UINT32                  LineCount;
1466     UINT32                  ShortCommentCount = 0;
1467 
1468 
1469     while (1)
1470     {
1471         /* Find comment open, within procedure level */
1472 
1473         SubBuffer = strstr (SubBuffer, "    /*");
1474         if (!SubBuffer)
1475         {
1476             goto Exit;
1477         }
1478 
1479         /* Find comment terminator */
1480 
1481         Ptr1 = strstr (SubBuffer, "*/");
1482         if (!Ptr1)
1483         {
1484             goto Exit;
1485         }
1486 
1487         /* Find next EOL (from original buffer) */
1488 
1489         Ptr2 = strstr (SubBuffer, "\n");
1490         if (!Ptr2)
1491         {
1492             goto Exit;
1493         }
1494 
1495         /* Ignore one-line comments */
1496 
1497         if (Ptr1 < Ptr2)
1498         {
1499             /* Normal comment, ignore and continue; */
1500 
1501             SubBuffer = Ptr2;
1502             continue;
1503         }
1504 
1505         /* Examine multi-line comment */
1506 
1507         LineCount = 1;
1508         while (Ptr1 > Ptr2)
1509         {
1510             /* Find next EOL */
1511 
1512             Ptr2++;
1513             Ptr2 = strstr (Ptr2, "\n");
1514             if (!Ptr2)
1515             {
1516                 goto Exit;
1517             }
1518 
1519             LineCount++;
1520         }
1521 
1522         SubBuffer = Ptr1;
1523 
1524         if (LineCount <= 3)
1525         {
1526             ShortCommentCount++;
1527         }
1528     }
1529 
1530 
1531 Exit:
1532 
1533     if (ShortCommentCount)
1534     {
1535         AsPrint ("Short Comments found", ShortCommentCount, Filename);
1536     }
1537 }
1538 #endif