Home | History | Annotate | Line # | Download | only in compiler
aslsupport.l revision 1.1
      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 - 2013, 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 }
    825