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