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