Home | History | Annotate | Line # | Download | only in compiler
aslsupport.l revision 1.18
      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 - 2023, 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 MERCHANTABILITY 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 preprocessor, 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    AslGbl_HasIncludeFiles = TRUE;
    108 
    109     /* Eat the entire line that contains the #line directive */
    110 
    111     AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer;
    112 
    113     while ((c = input()) != '\n' && c != EOF)
    114     {
    115         *AslGbl_LineBufPtr = (char) c;
    116         AslGbl_LineBufPtr++;
    117     }
    118     *AslGbl_LineBufPtr = 0;
    119 
    120     /* First argument is the actual line number */
    121 
    122     Token = strtok (AslGbl_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     AslGbl_CurrentColumn = 0;
    135     if (LineNumber > AslGbl_CurrentLineNumber)
    136     {
    137         for (i = 0; i < (LineNumber - AslGbl_CurrentLineNumber); i++)
    138         {
    139             FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
    140             AslGbl_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 = UtLocalCacheCalloc (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     AslGbl_CurrentLineOffset += AslGbl_CurrentColumn;
    163     AslGbl_CurrentColumn = 0;
    164     AslGbl_LineBufPtr = AslGbl_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     AslGbl_PreviousIncludeFilename = AslGbl_Files[ASL_FILE_INPUT].Filename;
    191     Fnode = AslGbl_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", AslGbl_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     AslGbl_IncludeFileStack = Fnode->Next;
    210 
    211     /* Reset global line counter and filename */
    212 
    213     AslGbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
    214     AslGbl_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 = AslGbl_IncludeFileStack;
    258     Fnode->State = YY_CURRENT_BUFFER;
    259     Fnode->Filename = AslGbl_Files[ASL_FILE_INPUT].Filename;
    260     Fnode->CurrentLineNumber = AslGbl_CurrentLineNumber;
    261 
    262     /* Push it on the stack */
    263 
    264     AslGbl_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     AslGbl_Files[ASL_FILE_INPUT].Filename =
    277         UtLocalCacheCalloc (strlen (Filename) + 1);
    278 
    279     strcpy (AslGbl_Files[ASL_FILE_INPUT].Filename, Filename);
    280 
    281     AslGbl_CurrentLineNumber = 1;
    282     yyin = InputFile;
    283 
    284     /* converter: reset the comment state to STANDARD_COMMENT */
    285 
    286     AslGbl_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 (AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
    308     {
    309         FlWriteFile (ASL_FILE_SOURCE_OUTPUT, AslGbl_CurrentLineBuffer,
    310             AslGbl_LineBufPtr - AslGbl_CurrentLineBuffer);
    311     }
    312 
    313     AslGbl_CurrentLineOffset += AslGbl_CurrentColumn;
    314     AslGbl_CurrentColumn = 0;
    315 
    316     AslGbl_CurrentLineNumber++;
    317     AslGbl_LogicalLineNumber++;
    318     AslGbl_LineBufPtr = AslGbl_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     AslGbl_InputByteCount++;
    348 
    349     /* Handle tabs. Convert to spaces */
    350 
    351     if (SourceChar == '\t')
    352     {
    353         SourceChar = ' ';
    354         Count = ASL_SPACES_PER_TAB -
    355                     (AslGbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
    356     }
    357 
    358     for (i = 0; i < Count; i++)
    359     {
    360         AslGbl_CurrentColumn++;
    361 
    362         /* Insert the character into the line buffer */
    363 
    364         *AslGbl_LineBufPtr = (UINT8) SourceChar;
    365         AslGbl_LineBufPtr++;
    366 
    367         if (AslGbl_LineBufPtr >
    368             (AslGbl_CurrentLineBuffer + (AslGbl_LineBufferSize - 1)))
    369         {
    370 #if 0
    371             /*
    372              * Warning if we have split a long source line.
    373              * <Probably overkill>
    374              */
    375             snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Max %u", Gbl_LineBufferSize);
    376             AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
    377                 AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    378                 AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    379                 AslGbl_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 (AcpiGbl_CaptureComments)
    392         {
    393             CvProcessCommentState ((char) 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     char                *p;
    421 
    422 
    423     switch (Type)
    424     {
    425     case 2:
    426 
    427         ++AslGbl_TotalKeywords;
    428         ++AslGbl_TotalNamedObjects;
    429         ++AslGbl_FilesList->TotalKeywords;
    430         ++AslGbl_FilesList->TotalNamedObjects;
    431         break;
    432 
    433     case 3:
    434 
    435         ++AslGbl_TotalKeywords;
    436         ++AslGbl_TotalExecutableOpcodes;
    437         ++AslGbl_FilesList->TotalKeywords;
    438         ++AslGbl_FilesList->TotalExecutableOpcodes;
    439         break;
    440 
    441     default:
    442 
    443         break;
    444     }
    445 
    446     for (p = yytext; *p != '\0'; p++)
    447     {
    448         AslInsertLineBuffer (*p);
    449         *AslGbl_LineBufPtr = 0;
    450     }
    451 }
    452 
    453 
    454 /*******************************************************************************
    455  *
    456  * FUNCTION:    AslDoComment
    457  *
    458  * PARAMETERS:  none
    459  *
    460  * RETURN:      none
    461  *
    462  * DESCRIPTION: Process a standard comment.
    463  *
    464  ******************************************************************************/
    465 
    466 static BOOLEAN
    467 AslDoComment (
    468     void)
    469 {
    470     int                     c;
    471     int                     c1 = 0;
    472     char                    *StringBuffer = AslGbl_MsgBuffer;
    473     char                    *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
    474     ASL_COMMENT_STATE       CurrentState = AslGbl_CommentState; /* to reference later on */
    475 
    476 
    477     AslInsertLineBuffer ('/');
    478     AslInsertLineBuffer ('*');
    479     if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
    480     {
    481         *StringBuffer = '/';
    482         ++StringBuffer;
    483         *StringBuffer = '*';
    484         ++StringBuffer;
    485     }
    486 
    487 loop:
    488 
    489     /* Eat chars until end-of-comment */
    490 
    491     while (((c = input ()) != '*') && (c != EOF))
    492     {
    493         AslInsertLineBuffer (c);
    494         if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
    495         {
    496             *StringBuffer = (char) c;
    497             ++StringBuffer;
    498         }
    499         c1 = c;
    500     }
    501 
    502     if (c == EOF)
    503     {
    504         goto EarlyEOF;
    505     }
    506 
    507     /*
    508      * Check for nested comment -- can help catch cases where a previous
    509      * comment was accidentally left unterminated
    510      */
    511     if ((c1 == '/') && (c == '*'))
    512     {
    513         AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
    514             AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    515             AslGbl_InputByteCount, AslGbl_CurrentColumn,
    516             AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
    517     }
    518 
    519     /* Comment is closed only if the NEXT character is a slash */
    520 
    521     AslInsertLineBuffer (c);
    522     if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
    523     {
    524         *StringBuffer = (char) c;
    525         ++StringBuffer;
    526     }
    527 
    528     if (((c1 = input ()) != '/') && (c1 != EOF))
    529     {
    530         unput (c1);
    531         goto loop;
    532     }
    533 
    534     if (c1 == EOF)
    535     {
    536         goto EarlyEOF;
    537     }
    538     if (StringBuffer > EndBuffer)
    539     {
    540         goto BufferOverflow;
    541     }
    542 
    543     AslInsertLineBuffer (c1);
    544     CvProcessComment (CurrentState, StringBuffer, c1);
    545     return (TRUE);
    546 
    547 
    548 EarlyEOF:
    549     /*
    550      * Premature End-Of-File
    551      */
    552     AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
    553         AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    554         AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    555         AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
    556     return (FALSE);
    557 
    558 
    559 BufferOverflow:
    560 
    561     /* Comment was too long */
    562 
    563     AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
    564         AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    565         AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    566         AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
    567     return (FALSE);
    568 
    569 }
    570 
    571 
    572 /*******************************************************************************
    573  *
    574  * FUNCTION:    AslDoCommentType2
    575  *
    576  * PARAMETERS:  none
    577  *
    578  * RETURN:      none
    579  *
    580  * DESCRIPTION: Process a new "//" comment. Inline comments will be converted
    581  *              to "/ *" standard comments.
    582  *
    583  ******************************************************************************/
    584 
    585 static BOOLEAN
    586 AslDoCommentType2 (
    587     void)
    588 {
    589     int                     c;
    590     char                    *StringBuffer = AslGbl_MsgBuffer;
    591     char                    *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
    592     ASL_COMMENT_STATE       CurrentState = AslGbl_CommentState;
    593 
    594 
    595     AslInsertLineBuffer ('/');
    596 
    597     if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
    598     {
    599         AslInsertLineBuffer ('*');
    600         *StringBuffer = '/';
    601         ++StringBuffer;
    602         *StringBuffer = '*';
    603         ++StringBuffer;
    604     }
    605     else
    606     {
    607         AslInsertLineBuffer ('/');
    608     }
    609 
    610     while (((c = input ()) != '\n') && (c != EOF))
    611     {
    612         AslInsertLineBuffer (c);
    613         if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
    614         {
    615             *StringBuffer = (char) c;
    616             ++StringBuffer;
    617         }
    618     }
    619 
    620     if (c == EOF)
    621     {
    622         /* End of file is OK, change to newline. Let parser detect EOF later */
    623 
    624         c = '\n';
    625     }
    626 
    627     if (StringBuffer > EndBuffer)
    628     {
    629         goto BufferOverflow;
    630     }
    631     AslInsertLineBuffer (c);
    632 
    633     CvProcessCommentType2 (CurrentState, StringBuffer);
    634     return (TRUE);
    635 
    636 
    637 BufferOverflow:
    638 
    639     /* Comment was too long */
    640 
    641     AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
    642         AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    643         AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    644         AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
    645     return (FALSE);
    646 
    647 }
    648 
    649 
    650 /*******************************************************************************
    651  *
    652  * FUNCTION:    AslDoStringLiteral
    653  *
    654  * PARAMETERS:  none
    655  *
    656  * RETURN:      none
    657  *
    658  * DESCRIPTION: Process a string literal (surrounded by quotes)
    659  *
    660  ******************************************************************************/
    661 
    662 static char
    663 AslDoStringLiteral (
    664     void)
    665 {
    666     char                *StringBuffer = AslGbl_MsgBuffer;
    667     char                *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
    668     char                *CleanString;
    669     int                 StringChar;
    670     UINT32              State = ASL_NORMAL_CHAR;
    671     UINT32              i = 0;
    672     UINT8               Digit;
    673     char                ConvertBuffer[4];
    674 
    675 
    676     /*
    677      * Eat chars until end-of-literal.
    678      * NOTE:  Put back the original surrounding quotes into the
    679      * source line buffer.
    680      */
    681     AslInsertLineBuffer ('\"');
    682     while ((StringChar = input()) != EOF)
    683     {
    684         AslInsertLineBuffer (StringChar);
    685 
    686 DoCharacter:
    687         switch (State)
    688         {
    689         case ASL_NORMAL_CHAR:
    690 
    691             switch (StringChar)
    692             {
    693             case '\\':
    694                 /*
    695                  * Special handling for backslash-escape sequence. We will
    696                  * toss the backslash and translate the escape char(s).
    697                  */
    698                 State = ASL_ESCAPE_SEQUENCE;
    699                 continue;
    700 
    701             case '\"':
    702 
    703                 /* String terminator */
    704 
    705                 goto CompletedString;
    706 
    707             default:
    708 
    709                 break;
    710             }
    711             break;
    712 
    713 
    714         case ASL_ESCAPE_SEQUENCE:
    715 
    716             State = ASL_NORMAL_CHAR;
    717             switch (StringChar)
    718             {
    719             case 'a':
    720 
    721                 StringChar = 0x07;      /* BELL */
    722                 break;
    723 
    724             case 'b':
    725 
    726                 StringChar = 0x08;      /* BACKSPACE */
    727                 break;
    728 
    729             case 'f':
    730 
    731                 StringChar = 0x0C;      /* FORMFEED */
    732                 break;
    733 
    734             case 'n':
    735 
    736                 StringChar = 0x0A;      /* LINEFEED */
    737                 break;
    738 
    739             case 'r':
    740 
    741                 StringChar = 0x0D;      /* CARRIAGE RETURN*/
    742                 break;
    743 
    744             case 't':
    745 
    746                 StringChar = 0x09;      /* HORIZONTAL TAB */
    747                 break;
    748 
    749             case 'v':
    750 
    751                 StringChar = 0x0B;      /* VERTICAL TAB */
    752                 break;
    753 
    754             case 'x':
    755 
    756                 State = ASL_HEX_CONSTANT;
    757                 i = 0;
    758                 continue;
    759 
    760             case '\'':                  /* Single Quote */
    761             case '\"':                  /* Double Quote */
    762             case '\\':                  /* Backslash */
    763 
    764                 break;
    765 
    766             default:
    767 
    768                 /* Check for an octal digit (0-7) */
    769 
    770                 if (ACPI_IS_OCTAL_DIGIT (StringChar))
    771                 {
    772                     State = ASL_OCTAL_CONSTANT;
    773                     ConvertBuffer[0] = (char) StringChar;
    774                     i = 1;
    775                     continue;
    776                 }
    777 
    778                 /* Unknown escape sequence issue warning, but use the character */
    779 
    780                 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
    781                     AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    782                     AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    783                     AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
    784                 break;
    785             }
    786             break;
    787 
    788 
    789         case ASL_OCTAL_CONSTANT:
    790 
    791             /* Up to three octal digits allowed */
    792 
    793             if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
    794                 (i > 2))
    795             {
    796                 /*
    797                  * Reached end of the constant. Convert the assembled ASCII
    798                  * string and resume processing of the next character
    799                  */
    800                 ConvertBuffer[i] = 0;
    801                 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);
    802 
    803                 /* Check for NULL or non-ascii character (ignore if so) */
    804 
    805                 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
    806                 {
    807                     AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
    808                         AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    809                         AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    810                         AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
    811                 }
    812                 else
    813                 {
    814                     *StringBuffer = (char) Digit;
    815                     StringBuffer++;
    816                     if (StringBuffer >= EndBuffer)
    817                     {
    818                         goto BufferOverflow;
    819                     }
    820                 }
    821 
    822                 State = ASL_NORMAL_CHAR;
    823                 goto DoCharacter;
    824                 break;
    825             }
    826 
    827             /* Append another digit of the constant */
    828 
    829             ConvertBuffer[i] = (char) StringChar;
    830             i++;
    831             continue;
    832 
    833         case ASL_HEX_CONSTANT:
    834 
    835             /* Up to two hex digits allowed */
    836 
    837             if (!isxdigit (StringChar) ||
    838                 (i > 1))
    839             {
    840                 /*
    841                  * Reached end of the constant. Convert the assembled ASCII
    842                  * string and resume processing of the next character
    843                  */
    844                 ConvertBuffer[i] = 0;
    845                 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);
    846 
    847                 /* Check for NULL or non-ascii character (ignore if so) */
    848 
    849                 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
    850                 {
    851                     AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
    852                         AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    853                         AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    854                         AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
    855                 }
    856                 else
    857                 {
    858                     *StringBuffer = (char) Digit;
    859                     StringBuffer++;
    860                     if (StringBuffer >= EndBuffer)
    861                     {
    862                         goto BufferOverflow;
    863                     }
    864                 }
    865 
    866                 State = ASL_NORMAL_CHAR;
    867                 goto DoCharacter;
    868                 break;
    869             }
    870 
    871             /* Append another digit of the constant */
    872 
    873             ConvertBuffer[i] = (char) StringChar;
    874             i++;
    875             continue;
    876 
    877         default:
    878 
    879             break;
    880         }
    881 
    882         /* Save the finished character */
    883 
    884         *StringBuffer = (char) StringChar;
    885         StringBuffer++;
    886         if (StringBuffer >= EndBuffer)
    887         {
    888             goto BufferOverflow;
    889         }
    890     }
    891 
    892     /*
    893      * Premature End-Of-File
    894      */
    895     AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
    896         AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    897         AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    898         AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
    899     return (FALSE);
    900 
    901 
    902 CompletedString:
    903     /*
    904      * Null terminate the input string and copy string to a new buffer
    905      */
    906     *StringBuffer = 0;
    907 
    908     CleanString = UtLocalCacheCalloc (strlen (AslGbl_MsgBuffer) + 1);
    909     strcpy (CleanString, AslGbl_MsgBuffer);
    910     AslCompilerlval.s = CleanString;
    911     return (TRUE);
    912 
    913 
    914 BufferOverflow:
    915 
    916     /* Literal was too long */
    917 
    918     AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
    919         AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
    920         AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
    921         AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
    922     return (FALSE);
    923 }
    924