1 /******************************************************************************
   2  *
   3  * Module Name: ascase - Source conversion - lower/upper case utilities
   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 void
  49 AsUppercaseTokens (
  50     char                    *Buffer,
  51     char                    *PrefixString);
  52 
  53 
  54 /******************************************************************************
  55  *
  56  * FUNCTION:    AsLowerCaseString
  57  *
  58  * DESCRIPTION: LowerCase all instances of a target string with a replacement
  59  *              string. Returns count of the strings replaced.
  60  *
  61  ******************************************************************************/
  62 
  63 int
  64 AsLowerCaseString (
  65     char                    *Target,
  66     char                    *Buffer)
  67 {
  68     char                    *SubString1;
  69     char                    *SubString2;
  70     char                    *SubBuffer;
  71     int                     TargetLength;
  72     int                     LowerCaseCount = 0;
  73     int                     i;
  74 
  75 
  76     TargetLength = strlen (Target);
  77 
  78     SubBuffer = Buffer;
  79     SubString1 = Buffer;
  80 
  81     while (SubString1)
  82     {
  83         /* Find the target string */
  84 
  85         SubString1 = strstr (SubBuffer, Target);
  86         if (!SubString1)
  87         {
  88             return (LowerCaseCount);
  89         }
  90 
  91         /*
  92          * Check for translation escape string -- means to ignore
  93          * blocks of code while replacing
  94          */
  95         if (Gbl_IgnoreTranslationEscapes)
  96         {
  97             SubString2 = NULL;
  98         }
  99         else
 100         {
 101             SubString2 = strstr (SubBuffer, AS_START_IGNORE);
 102         }
 103 
 104         if ((SubString2) &&
 105             (SubString2 < SubString1))
 106         {
 107             /* Find end of the escape block starting at "Substring2" */
 108 
 109             SubString2 = strstr (SubString2, AS_STOP_IGNORE);
 110             if (!SubString2)
 111             {
 112                 /* Didn't find terminator */
 113 
 114                 return (LowerCaseCount);
 115             }
 116 
 117             /* Move buffer to end of escape block and continue */
 118 
 119             SubBuffer = SubString2;
 120         }
 121 
 122         /* Do the actual replace if the target was found */
 123 
 124         else
 125         {
 126             if (!AsMatchExactWord (SubString1, TargetLength))
 127             {
 128                 SubBuffer = SubString1 + 1;
 129                 continue;
 130             }
 131 
 132             for (i = 0; i < TargetLength; i++)
 133             {
 134                 SubString1[i] = (char) tolower ((int) SubString1[i]);
 135             }
 136 
 137             SubBuffer = SubString1 + TargetLength;
 138 
 139             if ((Gbl_WidenDeclarations) && (!Gbl_StructDefs))
 140             {
 141                 if ((SubBuffer[0] == ' ') && (SubBuffer[1] == ' '))
 142                 {
 143                     AsInsertData (SubBuffer, "        ", 8);
 144                 }
 145             }
 146 
 147             LowerCaseCount++;
 148         }
 149     }
 150 
 151     return (LowerCaseCount);
 152 }
 153 
 154 
 155 /******************************************************************************
 156  *
 157  * FUNCTION:    AsMixedCaseToUnderscores
 158  *
 159  * DESCRIPTION: Converts mixed case identifiers to underscored identifiers.
 160  *              for example,
 161  *
 162  *              ThisUsefullyNamedIdentifier   becomes:
 163  *
 164  *              this_usefully_named_identifier
 165  *
 166  ******************************************************************************/
 167 
 168 void
 169 AsMixedCaseToUnderscores (
 170     char                    *Buffer,
 171     char                    *Filename)
 172 {
 173     UINT32                  Length;
 174     char                    *SubBuffer = Buffer;
 175     char                    *TokenEnd;
 176     char                    *TokenStart = NULL;
 177     char                    *SubString;
 178     UINT32                  LineNumber = 1;
 179     UINT32                  Count;
 180 
 181 
 182     /*
 183      * Examine the entire buffer (contains the entire file)
 184      * We are only interested in these tokens:
 185      *      Escape sequences - ignore entire sequence
 186      *      Single-quoted constants - ignore
 187      *      Quoted strings - ignore entire string
 188      *      Translation escape - starts with /,*,!
 189      *      Decimal and hex numeric constants - ignore entire token
 190      *      Entire uppercase token - ignore, it is a macro or define
 191      *      Starts with underscore, then a lowercase or digit: convert
 192      */
 193     while (*SubBuffer)
 194     {
 195         if (*SubBuffer == '\n')
 196         {
 197             LineNumber++;
 198             SubBuffer++;
 199             continue;
 200         }
 201 
 202         /* Ignore standard escape sequences (\n, \r, etc.)  Not Hex or Octal escapes */
 203 
 204         if (*SubBuffer == '\\')
 205         {
 206             SubBuffer += 2;
 207             continue;
 208         }
 209 
 210         /* Ignore single-quoted characters */
 211 
 212         if (*SubBuffer == '\'')
 213         {
 214             SubBuffer += 3;
 215             continue;
 216         }
 217 
 218         /* Ignore standard double-quoted strings */
 219 
 220         if (*SubBuffer == '"')
 221         {
 222             SubBuffer++;
 223             Count = 0;
 224             while (*SubBuffer != '"')
 225             {
 226                 Count++;
 227                 if ((!*SubBuffer) ||
 228                      (Count > 8192))
 229                 {
 230                     printf ("Found an unterminated quoted string!, line %u: %s\n",
 231                         LineNumber, Filename);
 232                     return;
 233                 }
 234 
 235                 /* Handle escape sequences */
 236 
 237                 if (*SubBuffer == '\\')
 238                 {
 239                     SubBuffer++;
 240                 }
 241 
 242                 SubBuffer++;
 243             }
 244             SubBuffer++;
 245             continue;
 246         }
 247 
 248         /*
 249          * Check for translation escape string. It means to ignore
 250          * blocks of code during this code conversion.
 251          */
 252         if ((SubBuffer[0] == '/') &&
 253             (SubBuffer[1] == '*') &&
 254             (SubBuffer[2] == '!'))
 255         {
 256             SubBuffer = strstr (SubBuffer, "!*/");
 257             if (!SubBuffer)
 258             {
 259                 printf ("Found an unterminated translation escape!, line %u: %s\n",
 260                     LineNumber, Filename);
 261                 return;
 262             }
 263             continue;
 264         }
 265 
 266         /* Ignore anything that starts with a number (0-9) */
 267 
 268         if (isdigit ((int) *SubBuffer))
 269         {
 270             /* Ignore hex constants */
 271 
 272             if ((SubBuffer[0] == '0') &&
 273                ((SubBuffer[1] == 'x') || (SubBuffer[1] == 'X')))
 274             {
 275                 SubBuffer += 2;
 276             }
 277 
 278             /* Skip over all digits, both decimal and hex */
 279 
 280             while (isxdigit ((int) *SubBuffer))
 281             {
 282                 SubBuffer++;
 283             }
 284             TokenStart = NULL;
 285             continue;
 286         }
 287 
 288         /*
 289          * Check for fully upper case identifiers. These are usually macros
 290          * or defines. Allow decimal digits and embedded underscores.
 291          */
 292         if (isupper ((int) *SubBuffer))
 293         {
 294             SubString = SubBuffer + 1;
 295             while ((isupper ((int) *SubString)) ||
 296                    (isdigit ((int) *SubString)) ||
 297                    (*SubString == '_'))
 298             {
 299                 SubString++;
 300             }
 301 
 302             /*
 303              * For the next character, anything other than a lower case
 304              * means that the identifier has terminated, and contains
 305              * exclusively Uppers/Digits/Underscores. Ignore the entire
 306              * identifier.
 307              */
 308             if (!islower ((int) *SubString))
 309             {
 310                 SubBuffer = SubString + 1;
 311                 continue;
 312             }
 313         }
 314 
 315         /*
 316          * These forms may indicate an identifier that can be converted:
 317          *      <UpperCase><LowerCase> (Ax)
 318          *      <UpperCase><Number> (An)
 319          */
 320         if (isupper ((int) SubBuffer[0]) &&
 321           ((islower ((int) SubBuffer[1])) || isdigit ((int) SubBuffer[1])))
 322         {
 323             TokenStart = SubBuffer;
 324             SubBuffer++;
 325 
 326             while (1)
 327             {
 328                 /* Walk over the lower case letters and decimal digits */
 329 
 330                 while (islower ((int) *SubBuffer) ||
 331                        isdigit ((int) *SubBuffer))
 332                 {
 333                     SubBuffer++;
 334                 }
 335 
 336                 /* Check for end of line or end of token */
 337 
 338                 if (*SubBuffer == '\n')
 339                 {
 340                     LineNumber++;
 341                     break;
 342                 }
 343 
 344                 if (*SubBuffer == ' ')
 345                 {
 346                     /* Check for form "Axx - " in a parameter header description */
 347 
 348                     while (*SubBuffer == ' ')
 349                     {
 350                         SubBuffer++;
 351                     }
 352 
 353                     SubBuffer--;
 354                     if ((SubBuffer[1] == '-') &&
 355                         (SubBuffer[2] == ' '))
 356                     {
 357                         if (TokenStart)
 358                         {
 359                             *TokenStart = (char) tolower ((int) *TokenStart);
 360                         }
 361                     }
 362                     break;
 363                 }
 364 
 365                 /*
 366                  * Ignore these combinations:
 367                  *      <Letter><Digit><UpperCase>
 368                  *      <Digit><Digit><UpperCase>
 369                  *      <Underscore><Digit><UpperCase>
 370                  */
 371                 if (isdigit ((int) *SubBuffer))
 372                 {
 373                     if (isalnum ((int) *(SubBuffer-1)) ||
 374                         *(SubBuffer-1) == '_')
 375                     {
 376                         break;
 377                     }
 378                 }
 379 
 380                 /* Ignore token if next character is not uppercase or digit */
 381 
 382                 if (!isupper ((int) *SubBuffer) &&
 383                     !isdigit ((int) *SubBuffer))
 384                 {
 385                     break;
 386                 }
 387 
 388                 /*
 389                  * Form <UpperCase><LowerCaseLetters><UpperCase> (AxxB):
 390                  * Convert leading character of the token to lower case
 391                  */
 392                 if (TokenStart)
 393                 {
 394                     *TokenStart = (char) tolower ((int) *TokenStart);
 395                     TokenStart = NULL;
 396                 }
 397 
 398                 /* Find the end of this identifier (token) */
 399 
 400                 TokenEnd = SubBuffer - 1;
 401                 while ((isalnum ((int) *TokenEnd)) ||
 402                        (*TokenEnd == '_'))
 403                 {
 404                     TokenEnd++;
 405                 }
 406 
 407                 SubString = TokenEnd;
 408                 Length = 0;
 409 
 410                 while (*SubString != '\n')
 411                 {
 412                     /*
 413                      * If we have at least two trailing spaces, we can get rid of
 414                      * one to make up for the newly inserted underscore. This will
 415                      * help preserve the alignment of the text
 416                      */
 417                     if ((SubString[0] == ' ') &&
 418                         (SubString[1] == ' '))
 419                     {
 420                         Length = SubString - SubBuffer - 1;
 421                         break;
 422                     }
 423 
 424                     SubString++;
 425                 }
 426 
 427                 if (!Length)
 428                 {
 429                     Length = strlen (&SubBuffer[0]);
 430                 }
 431 
 432                 /*
 433                  * Within this identifier, convert this pair of letters that
 434                  * matches the form:
 435                  *
 436                  *      <LowerCase><UpperCase>
 437                  * to
 438                  *      <LowerCase><Underscore><LowerCase>
 439                  */
 440                 Gbl_MadeChanges = TRUE;
 441 
 442                 /* Insert the underscore */
 443 
 444                 memmove (&SubBuffer[1], &SubBuffer[0], Length + 1);
 445                 SubBuffer[0] = '_';
 446 
 447                 /*
 448                  * If we have <UpperCase><UpperCase>, leave them as-is
 449                  * Enables transforms like:
 450                  *      LocalFADT -> local_FADT
 451                  */
 452                 if (isupper ((int) SubBuffer[2]))
 453                 {
 454                     SubBuffer += 1;
 455                     break;
 456                 }
 457 
 458                 /* Lower case the original upper case letter */
 459 
 460                 SubBuffer[1] = (char) tolower ((int) SubBuffer[1]);
 461                 SubBuffer += 2;
 462             }
 463         }
 464 
 465         SubBuffer++;
 466     }
 467 }
 468 
 469 
 470 /******************************************************************************
 471  *
 472  * FUNCTION:    AsLowerCaseIdentifiers
 473  *
 474  * DESCRIPTION: Converts mixed case identifiers to lower case. Leaves comments,
 475  *              quoted strings, and all-upper-case macros alone.
 476  *
 477  ******************************************************************************/
 478 
 479 void
 480 AsLowerCaseIdentifiers (
 481     char                    *Buffer)
 482 {
 483     char                    *SubBuffer = Buffer;
 484 
 485 
 486     while (*SubBuffer)
 487     {
 488         /*
 489          * Check for translation escape string -- means to ignore
 490          * blocks of code while replacing
 491          */
 492         if ((SubBuffer[0] == '/') &&
 493             (SubBuffer[1] == '*') &&
 494             (SubBuffer[2] == '!'))
 495         {
 496             SubBuffer = strstr (SubBuffer, "!*/");
 497             if (!SubBuffer)
 498             {
 499                 return;
 500             }
 501         }
 502 
 503         /* Ignore comments */
 504 
 505         if ((SubBuffer[0] == '/') &&
 506             (SubBuffer[1] == '*'))
 507         {
 508             SubBuffer = strstr (SubBuffer, "*/");
 509             if (!SubBuffer)
 510             {
 511                 return;
 512             }
 513 
 514             SubBuffer += 2;
 515         }
 516 
 517         /* Ignore quoted strings */
 518 
 519         if ((SubBuffer[0] == '\"') && (SubBuffer[1] != '\''))
 520         {
 521             SubBuffer++;
 522 
 523             /* Find the closing quote */
 524 
 525             while (SubBuffer[0])
 526             {
 527                 /* Ignore escaped quote characters */
 528 
 529                 if (SubBuffer[0] == '\\')
 530                 {
 531                     SubBuffer++;
 532                 }
 533                 else if (SubBuffer[0] == '\"')
 534                 {
 535                     SubBuffer++;
 536                     break;
 537                 }
 538                 SubBuffer++;
 539             }
 540         }
 541 
 542         if (!SubBuffer[0])
 543         {
 544             return;
 545         }
 546 
 547         /*
 548          * Only lower case if we have an upper followed by a lower
 549          * This leaves the all-uppercase things (macros, etc.) intact
 550          */
 551         if ((isupper ((int) SubBuffer[0])) &&
 552             (islower ((int) SubBuffer[1])))
 553         {
 554             Gbl_MadeChanges = TRUE;
 555             *SubBuffer = (char) tolower ((int) *SubBuffer);
 556         }
 557 
 558         SubBuffer++;
 559     }
 560 }
 561 
 562 
 563 /******************************************************************************
 564  *
 565  * FUNCTION:    AsUppercaseTokens
 566  *
 567  * DESCRIPTION: Force to uppercase all tokens that begin with the prefix string.
 568  *              used to convert mixed-case macros and constants to uppercase.
 569  *
 570  ******************************************************************************/
 571 
 572 void
 573 AsUppercaseTokens (
 574     char                    *Buffer,
 575     char                    *PrefixString)
 576 {
 577     char                    *SubBuffer;
 578     char                    *TokenEnd;
 579     char                    *SubString;
 580     int                     i;
 581     UINT32                  Length;
 582 
 583 
 584     SubBuffer = Buffer;
 585 
 586     while (SubBuffer)
 587     {
 588         SubBuffer = strstr (SubBuffer, PrefixString);
 589         if (SubBuffer)
 590         {
 591             TokenEnd = SubBuffer;
 592             while ((isalnum ((int) *TokenEnd)) || (*TokenEnd == '_'))
 593             {
 594                 TokenEnd++;
 595             }
 596 
 597             for (i = 0; i < (TokenEnd - SubBuffer); i++)
 598             {
 599                 if ((islower ((int) SubBuffer[i])) &&
 600                     (isupper ((int) SubBuffer[i+1])))
 601                 {
 602 
 603                     SubString = TokenEnd;
 604                     Length = 0;
 605 
 606                     while (*SubString != '\n')
 607                     {
 608                         if ((SubString[0] == ' ') &&
 609                             (SubString[1] == ' '))
 610                         {
 611                             Length = SubString - &SubBuffer[i] - 2;
 612                             break;
 613                         }
 614 
 615                         SubString++;
 616                     }
 617 
 618                     if (!Length)
 619                     {
 620                         Length = strlen (&SubBuffer[i+1]);
 621                     }
 622 
 623                     memmove (&SubBuffer[i+2], &SubBuffer[i+1], (Length+1));
 624                     SubBuffer[i+1] = '_';
 625                     i +=2;
 626                     TokenEnd++;
 627                 }
 628             }
 629 
 630             for (i = 0; i < (TokenEnd - SubBuffer); i++)
 631             {
 632                 SubBuffer[i] = (char) toupper ((int) SubBuffer[i]);
 633             }
 634 
 635             SubBuffer = TokenEnd;
 636         }
 637     }
 638 }