1 /******************************************************************************
   2  *
   3  * Module Name: aslsupport.l - Flex/lex scanner C support routines.
   4  *              NOTE: Included into aslcompile.l, not compiled by itself.
   5  *
   6  *****************************************************************************/
   7 
   8 /*
   9  * Copyright (C) 2000 - 2014, Intel Corp.
  10  * All rights reserved.
  11  *
  12  * Redistribution and use in source and binary forms, with or without
  13  * modification, are permitted provided that the following conditions
  14  * are met:
  15  * 1. Redistributions of source code must retain the above copyright
  16  *    notice, this list of conditions, and the following disclaimer,
  17  *    without modification.
  18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19  *    substantially similar to the "NO WARRANTY" disclaimer below
  20  *    ("Disclaimer") and any redistribution must be conditioned upon
  21  *    including a substantially similar Disclaimer requirement for further
  22  *    binary redistribution.
  23  * 3. Neither the names of the above-listed copyright holders nor the names
  24  *    of any contributors may be used to endorse or promote products derived
  25  *    from this software without specific prior written permission.
  26  *
  27  * Alternatively, this software may be distributed under the terms of the
  28  * GNU General Public License ("GPL") version 2 as published by the Free
  29  * Software Foundation.
  30  *
  31  * NO WARRANTY
  32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42  * POSSIBILITY OF SUCH DAMAGES.
  43  */
  44 
  45 
  46 /* Configuration */
  47 
  48 #define ASL_SPACES_PER_TAB      4
  49 
  50 #define ASL_NORMAL_CHAR         0
  51 #define ASL_ESCAPE_SEQUENCE     1
  52 #define ASL_OCTAL_CONSTANT      2
  53 #define ASL_HEX_CONSTANT        3
  54 
  55 
  56 /* File node - used for "Include" operator file stack */
  57 
  58 typedef struct asl_file_node
  59 {
  60     FILE                    *File;
  61     UINT32                  CurrentLineNumber;
  62     YY_BUFFER_STATE         State;
  63     char                    *Filename;
  64     struct asl_file_node    *Next;
  65 
  66 } ASL_FILE_NODE;
  67 
  68 /* File stack for the "Include" operator (NOT #include operator) */
  69 
  70 ASL_FILE_NODE               *Gbl_IncludeFileStack = NULL;
  71 
  72 
  73 /*******************************************************************************
  74  *
  75  * FUNCTION:    AslDoLineDirective
  76  *
  77  * PARAMETERS:  None. Uses input() to access current source code line
  78  *
  79  * RETURN:      Updates global line number and filename
  80  *
  81  * DESCRIPTION: Handle #line directives emitted by the preprocessor.
  82  *
  83  * The #line directive is emitted by the preprocesser, and is used to
  84  * pass through line numbers from the original source code file to the
  85  * preprocessor output file (.i). This allows any compiler-generated
  86  * error messages to be displayed with the correct line number.
  87  *
  88  ******************************************************************************/
  89 
  90 static void
  91 AslDoLineDirective (
  92     void)
  93 {
  94     int                     c;
  95     char                    *Token;
  96     UINT32                  LineNumber;
  97     char                    *Filename;
  98     UINT32                  i;
  99 
 100 
 101     /* Eat the entire line that contains the #line directive */
 102 
 103     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
 104 
 105     while ((c = input()) != '\n' && c != EOF)
 106     {
 107         *Gbl_LineBufPtr = c;
 108         Gbl_LineBufPtr++;
 109     }
 110     *Gbl_LineBufPtr = 0;
 111 
 112     /* First argument is the actual line number */
 113 
 114     Token = strtok (Gbl_CurrentLineBuffer, " ");
 115     if (!Token)
 116     {
 117         goto ResetAndExit;
 118     }
 119 
 120     /* First argument is the line number */
 121 
 122     LineNumber = (UINT32) UtDoConstant (Token);
 123 
 124     /* Emit the appropriate number of newlines */
 125 
 126     Gbl_CurrentColumn = 0;
 127     if (LineNumber > Gbl_CurrentLineNumber)
 128     {
 129         for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++)
 130         {
 131             FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
 132             Gbl_CurrentColumn++;
 133         }
 134     }
 135 
 136     FlSetLineNumber (LineNumber);
 137 
 138     /* Second argument is the optional filename (in double quotes) */
 139 
 140     Token = strtok (NULL, " \"");
 141     if (Token)
 142     {
 143         Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1);
 144         strcpy (Filename, Token);
 145         FlSetFilename (Filename);
 146     }
 147 
 148     /* Third argument is not supported at this time */
 149 
 150 ResetAndExit:
 151 
 152     /* Reset globals for a new line */
 153 
 154     Gbl_CurrentLineOffset += Gbl_CurrentColumn;
 155     Gbl_CurrentColumn = 0;
 156     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
 157 }
 158 
 159 
 160 /*******************************************************************************
 161  *
 162  * FUNCTION:    AslPopInputFileStack
 163  *
 164  * PARAMETERS:  None
 165  *
 166  * RETURN:      0 if a node was popped, -1 otherwise
 167  *
 168  * DESCRIPTION: Pop the top of the input file stack and point the parser to
 169  *              the saved parse buffer contained in the fnode. Also, set the
 170  *              global line counters to the saved values. This function is
 171  *              called when an include file reaches EOF.
 172  *
 173  ******************************************************************************/
 174 
 175 int
 176 AslPopInputFileStack (
 177     void)
 178 {
 179     ASL_FILE_NODE           *Fnode;
 180 
 181 
 182     Fnode = Gbl_IncludeFileStack;
 183     DbgPrint (ASL_PARSE_OUTPUT, "\nPop InputFile Stack, Fnode %p\n\n", Fnode);
 184 
 185     if (!Fnode)
 186     {
 187         return (-1);
 188     }
 189 
 190     /* Close the current include file */
 191 
 192     fclose (yyin);
 193 
 194     /* Update the top-of-stack */
 195 
 196     Gbl_IncludeFileStack = Fnode->Next;
 197 
 198     /* Reset global line counter and filename */
 199 
 200     Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
 201     Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
 202 
 203     /* Point the parser to the popped file */
 204 
 205     yy_delete_buffer (YY_CURRENT_BUFFER);
 206     yy_switch_to_buffer (Fnode->State);
 207 
 208     /* All done with this node */
 209 
 210     ACPI_FREE (Fnode);
 211     return (0);
 212 }
 213 
 214 
 215 /*******************************************************************************
 216  *
 217  * FUNCTION:    AslPushInputFileStack
 218  *
 219  * PARAMETERS:  InputFile           - Open file pointer
 220  *              Filename            - Name of the file
 221  *
 222  * RETURN:      None
 223  *
 224  * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
 225  *              to this file. Called when an include file is successfully
 226  *              opened.
 227  *
 228  ******************************************************************************/
 229 
 230 void
 231 AslPushInputFileStack (
 232     FILE                    *InputFile,
 233     char                    *Filename)
 234 {
 235     ASL_FILE_NODE           *Fnode;
 236     YY_BUFFER_STATE         State;
 237 
 238 
 239     /* Save the current state in an Fnode */
 240 
 241     Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
 242 
 243     Fnode->File                 = yyin;
 244     Fnode->Next                 = Gbl_IncludeFileStack;
 245     Fnode->State                = YY_CURRENT_BUFFER;
 246     Fnode->CurrentLineNumber    = Gbl_CurrentLineNumber;
 247     Fnode->Filename             = Gbl_Files[ASL_FILE_INPUT].Filename;
 248 
 249     /* Push it on the stack */
 250 
 251     Gbl_IncludeFileStack = Fnode;
 252 
 253     /* Point the parser to this file */
 254 
 255     State = yy_create_buffer (InputFile, YY_BUF_SIZE);
 256     yy_switch_to_buffer (State);
 257 
 258     DbgPrint (ASL_PARSE_OUTPUT, "\nPush InputFile Stack, returning %p\n\n", InputFile);
 259 
 260     /* Reset the global line count and filename */
 261 
 262     Gbl_Files[ASL_FILE_INPUT].Filename = Filename;
 263     Gbl_CurrentLineNumber = 1;
 264     yyin = InputFile;
 265 }
 266 
 267 
 268 /*******************************************************************************
 269  *
 270  * FUNCTION:    AslResetCurrentLineBuffer
 271  *
 272  * PARAMETERS:  None
 273  *
 274  * RETURN:      None
 275  *
 276  * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
 277  *
 278  ******************************************************************************/
 279 
 280 void
 281 AslResetCurrentLineBuffer (
 282     void)
 283 {
 284 
 285     if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
 286     {
 287         FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
 288             Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
 289     }
 290 
 291     Gbl_CurrentLineOffset += Gbl_CurrentColumn;
 292     Gbl_CurrentColumn = 0;
 293 
 294     Gbl_CurrentLineNumber++;
 295     Gbl_LogicalLineNumber++;
 296     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
 297 }
 298 
 299 
 300 /*******************************************************************************
 301  *
 302  * FUNCTION:    AslInsertLineBuffer
 303  *
 304  * PARAMETERS:  SourceChar      - One char from the input ASL source file
 305  *
 306  * RETURN:      None
 307  *
 308  * DESCRIPTION: Put one character of the source file into the temp line buffer
 309  *
 310  ******************************************************************************/
 311 
 312 void
 313 AslInsertLineBuffer (
 314     int                     SourceChar)
 315 {
 316     UINT32                  i;
 317     UINT32                  Count = 1;
 318 
 319 
 320     if (SourceChar == EOF)
 321     {
 322         return;
 323     }
 324 
 325     Gbl_InputByteCount++;
 326 
 327     /* Handle tabs. Convert to spaces */
 328 
 329     if (SourceChar == '\t')
 330     {
 331         SourceChar = ' ';
 332         Count = ASL_SPACES_PER_TAB -
 333                     (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
 334     }
 335 
 336     for (i = 0; i < Count; i++)
 337     {
 338         Gbl_CurrentColumn++;
 339 
 340         /* Insert the character into the line buffer */
 341 
 342         *Gbl_LineBufPtr = (UINT8) SourceChar;
 343         Gbl_LineBufPtr++;
 344 
 345         if (Gbl_LineBufPtr > (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1)))
 346         {
 347 #if 0
 348             /*
 349              * Warning if we have split a long source line.
 350              * <Probably overkill>
 351              */
 352             sprintf (MsgBuffer, "Max %u", Gbl_LineBufferSize);
 353             AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
 354                             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 355                             Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 356                             Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
 357 #endif
 358 
 359             AslResetCurrentLineBuffer ();
 360         }
 361         else if (SourceChar == '\n')
 362         {
 363             /* End of line */
 364 
 365             AslResetCurrentLineBuffer ();
 366         }
 367     }
 368 }
 369 
 370 
 371 /*******************************************************************************
 372  *
 373  * FUNCTION:    count
 374  *
 375  * PARAMETERS:  yytext      - Contains the matched keyword.
 376  *              Type        - Keyword/Character type:
 377  *                             0 = anything except a keyword
 378  *                             1 = pseudo-keywords
 379  *                             2 = non-executable ASL keywords
 380  *                             3 = executable ASL keywords
 381  *
 382  * RETURN:      None
 383  *
 384  * DESCRIPTION: Count keywords and put them into the line buffer
 385  *
 386  ******************************************************************************/
 387 
 388 static void
 389 count (
 390     int                 Type)
 391 {
 392     int                 i;
 393 
 394 
 395     switch (Type)
 396     {
 397     case 2:
 398 
 399         TotalKeywords++;
 400         TotalNamedObjects++;
 401         break;
 402 
 403     case 3:
 404 
 405         TotalKeywords++;
 406         TotalExecutableOpcodes++;
 407         break;
 408 
 409     default:
 410 
 411         break;
 412     }
 413 
 414     for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
 415     {
 416         AslInsertLineBuffer (yytext[i]);
 417         *Gbl_LineBufPtr = 0;
 418     }
 419 }
 420 
 421 
 422 /*******************************************************************************
 423  *
 424  * FUNCTION:    AslDoComment
 425  *
 426  * PARAMETERS:  none
 427  *
 428  * RETURN:      none
 429  *
 430  * DESCRIPTION: Process a standard comment.
 431  *
 432  ******************************************************************************/
 433 
 434 static char
 435 AslDoComment (
 436     void)
 437 {
 438     int                 c;
 439     int                 c1 = 0;
 440 
 441 
 442     AslInsertLineBuffer ('/');
 443     AslInsertLineBuffer ('*');
 444 
 445 loop:
 446 
 447     /* Eat chars until end-of-comment */
 448 
 449     while ((c = input()) != '*' && c != EOF)
 450     {
 451         AslInsertLineBuffer (c);
 452         c1 = c;
 453     }
 454 
 455     if (c == EOF)
 456     {
 457         goto EarlyEOF;
 458     }
 459 
 460     /*
 461      * Check for nested comment -- can help catch cases where a previous
 462      * comment was accidently left unterminated
 463      */
 464     if ((c1 == '/') && (c == '*'))
 465     {
 466         AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
 467                         Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 468                         Gbl_InputByteCount, Gbl_CurrentColumn,
 469                         Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
 470     }
 471 
 472     /* Comment is closed only if the NEXT character is a slash */
 473 
 474     AslInsertLineBuffer (c);
 475 
 476     if ((c1 = input()) != '/' && c1 != EOF)
 477     {
 478         unput(c1);
 479         goto loop;
 480     }
 481 
 482     if (c1 == EOF)
 483     {
 484         goto EarlyEOF;
 485     }
 486 
 487     AslInsertLineBuffer (c1);
 488     return (TRUE);
 489 
 490 
 491 EarlyEOF:
 492     /*
 493      * Premature End-Of-File
 494      */
 495     AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
 496                     Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 497                     Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 498                     Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
 499     return (FALSE);
 500 }
 501 
 502 
 503 /*******************************************************************************
 504  *
 505  * FUNCTION:    AslDoCommentType2
 506  *
 507  * PARAMETERS:  none
 508  *
 509  * RETURN:      none
 510  *
 511  * DESCRIPTION: Process a new "//" comment.
 512  *
 513  ******************************************************************************/
 514 
 515 static char
 516 AslDoCommentType2 (
 517     void)
 518 {
 519     int                 c;
 520 
 521 
 522     AslInsertLineBuffer ('/');
 523     AslInsertLineBuffer ('/');
 524 
 525     while ((c = input()) != '\n' && c != EOF)
 526     {
 527         AslInsertLineBuffer (c);
 528     }
 529 
 530     if (c == EOF)
 531     {
 532         /* End of file is OK, change to newline. Let parser detect EOF later */
 533 
 534         c = '\n';
 535     }
 536 
 537     AslInsertLineBuffer (c);
 538     return (TRUE);
 539 }
 540 
 541 
 542 /*******************************************************************************
 543  *
 544  * FUNCTION:    AslDoStringLiteral
 545  *
 546  * PARAMETERS:  none
 547  *
 548  * RETURN:      none
 549  *
 550  * DESCRIPTION: Process a string literal (surrounded by quotes)
 551  *
 552  ******************************************************************************/
 553 
 554 static char
 555 AslDoStringLiteral (
 556     void)
 557 {
 558     char                *StringBuffer = MsgBuffer;
 559     char                *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
 560     char                *CleanString;
 561     int                 StringChar;
 562     UINT32              State = ASL_NORMAL_CHAR;
 563     UINT32              i = 0;
 564     UINT8               Digit;
 565     char                ConvertBuffer[4];
 566 
 567 
 568     /*
 569      * Eat chars until end-of-literal.
 570      * NOTE:  Put back the original surrounding quotes into the
 571      * source line buffer.
 572      */
 573     AslInsertLineBuffer ('\"');
 574     while ((StringChar = input()) != EOF)
 575     {
 576         AslInsertLineBuffer (StringChar);
 577 
 578 DoCharacter:
 579         switch (State)
 580         {
 581         case ASL_NORMAL_CHAR:
 582 
 583             switch (StringChar)
 584             {
 585             case '\\':
 586                 /*
 587                  * Special handling for backslash-escape sequence. We will
 588                  * toss the backslash and translate the escape char(s).
 589                  */
 590                 State = ASL_ESCAPE_SEQUENCE;
 591                 continue;
 592 
 593             case '\"':
 594 
 595                 /* String terminator */
 596 
 597                 goto CompletedString;
 598 
 599             default:
 600 
 601                 break;
 602             }
 603             break;
 604 
 605 
 606         case ASL_ESCAPE_SEQUENCE:
 607 
 608             State = ASL_NORMAL_CHAR;
 609             switch (StringChar)
 610             {
 611             case 'a':
 612 
 613                 StringChar = 0x07;      /* BELL */
 614                 break;
 615 
 616             case 'b':
 617 
 618                 StringChar = 0x08;      /* BACKSPACE */
 619                 break;
 620 
 621             case 'f':
 622 
 623                 StringChar = 0x0C;      /* FORMFEED */
 624                 break;
 625 
 626             case 'n':
 627 
 628                 StringChar = 0x0A;      /* LINEFEED */
 629                 break;
 630 
 631             case 'r':
 632 
 633                 StringChar = 0x0D;      /* CARRIAGE RETURN*/
 634                 break;
 635 
 636             case 't':
 637 
 638                 StringChar = 0x09;      /* HORIZONTAL TAB */
 639                 break;
 640 
 641             case 'v':
 642 
 643                 StringChar = 0x0B;      /* VERTICAL TAB */
 644                 break;
 645 
 646             case 'x':
 647 
 648                 State = ASL_HEX_CONSTANT;
 649                 i = 0;
 650                 continue;
 651 
 652             case '\'':                  /* Single Quote */
 653             case '\"':                  /* Double Quote */
 654             case '\\':                  /* Backslash */
 655 
 656                 break;
 657 
 658             default:
 659 
 660                 /* Check for an octal digit (0-7) */
 661 
 662                 if (ACPI_IS_OCTAL_DIGIT (StringChar))
 663                 {
 664                     State = ASL_OCTAL_CONSTANT;
 665                     ConvertBuffer[0] = StringChar;
 666                     i = 1;
 667                     continue;
 668                 }
 669 
 670                 /* Unknown escape sequence issue warning, but use the character */
 671 
 672                 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
 673                                 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 674                                 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 675                                 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
 676                 break;
 677             }
 678             break;
 679 
 680 
 681         case ASL_OCTAL_CONSTANT:
 682 
 683             /* Up to three octal digits allowed */
 684 
 685             if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
 686                 (i > 2))
 687             {
 688                 /*
 689                  * Reached end of the constant. Convert the assembled ASCII
 690                  * string and resume processing of the next character
 691                  */
 692                 ConvertBuffer[i] = 0;
 693                 Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 8);
 694 
 695                 /* Check for NULL or non-ascii character (ignore if so) */
 696 
 697                 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
 698                 {
 699                     AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
 700                                     Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 701                                     Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 702                                     Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
 703                 }
 704                 else
 705                 {
 706                     *StringBuffer = (char) Digit;
 707                     StringBuffer++;
 708                     if (StringBuffer >= EndBuffer)
 709                     {
 710                         goto BufferOverflow;
 711                     }
 712                 }
 713 
 714                 State = ASL_NORMAL_CHAR;
 715                 goto DoCharacter;
 716                 break;
 717             }
 718 
 719             /* Append another digit of the constant */
 720 
 721             ConvertBuffer[i] = StringChar;
 722             i++;
 723             continue;
 724 
 725         case ASL_HEX_CONSTANT:
 726 
 727             /* Up to two hex digits allowed */
 728 
 729             if (!ACPI_IS_XDIGIT (StringChar) ||
 730                 (i > 1))
 731             {
 732                 /*
 733                  * Reached end of the constant. Convert the assembled ASCII
 734                  * string and resume processing of the next character
 735                  */
 736                 ConvertBuffer[i] = 0;
 737                 Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 16);
 738 
 739                 /* Check for NULL or non-ascii character (ignore if so) */
 740 
 741                 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
 742                 {
 743                     AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
 744                                     Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 745                                     Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 746                                     Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
 747                 }
 748                 else
 749                 {
 750                     *StringBuffer = (char) Digit;
 751                     StringBuffer++;
 752                     if (StringBuffer >= EndBuffer)
 753                     {
 754                         goto BufferOverflow;
 755                     }
 756                 }
 757 
 758                 State = ASL_NORMAL_CHAR;
 759                 goto DoCharacter;
 760                 break;
 761             }
 762 
 763             /* Append another digit of the constant */
 764 
 765             ConvertBuffer[i] = StringChar;
 766             i++;
 767             continue;
 768 
 769         default:
 770 
 771             break;
 772         }
 773 
 774         /* Save the finished character */
 775 
 776         *StringBuffer = StringChar;
 777         StringBuffer++;
 778         if (StringBuffer >= EndBuffer)
 779         {
 780             goto BufferOverflow;
 781         }
 782     }
 783 
 784     /*
 785      * Premature End-Of-File
 786      */
 787     AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
 788                     Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 789                     Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 790                     Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
 791     return (FALSE);
 792 
 793 
 794 CompletedString:
 795     /*
 796      * Null terminate the input string and copy string to a new buffer
 797      */
 798     *StringBuffer = 0;
 799 
 800     CleanString = UtGetStringBuffer (strlen (MsgBuffer) + 1);
 801     if (!CleanString)
 802     {
 803         AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
 804                         Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 805                         Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 806                         Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
 807         return (FALSE);
 808     }
 809 
 810     ACPI_STRCPY (CleanString, MsgBuffer);
 811     AslCompilerlval.s = CleanString;
 812     return (TRUE);
 813 
 814 
 815 BufferOverflow:
 816 
 817     /* Literal was too long */
 818 
 819     AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
 820                     Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
 821                     Gbl_CurrentLineOffset, Gbl_CurrentColumn,
 822                     Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
 823     return (FALSE);
 824 }