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 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117/* Configuration */
118
119#define ASL_SPACES_PER_TAB      4
120
121#define ASL_NORMAL_CHAR         0
122#define ASL_ESCAPE_SEQUENCE     1
123#define ASL_OCTAL_CONSTANT      2
124#define ASL_HEX_CONSTANT        3
125
126
127/* File node - used for "Include" operator file stack */
128
129typedef struct asl_file_node
130{
131    FILE                    *File;
132    UINT32                  CurrentLineNumber;
133    YY_BUFFER_STATE         State;
134    char                    *Filename;
135    struct asl_file_node    *Next;
136
137} ASL_FILE_NODE;
138
139/* File stack for the "Include" operator (NOT #include operator) */
140
141ASL_FILE_NODE               *Gbl_IncludeFileStack = NULL;
142
143
144/*******************************************************************************
145 *
146 * FUNCTION:    AslParserCleanup
147 *
148 * Used to delete the current buffer
149 *
150 ******************************************************************************/
151
152void
153AslParserCleanup (
154    void)
155{
156
157    yy_delete_buffer (YY_CURRENT_BUFFER);
158}
159
160
161/*******************************************************************************
162 *
163 * FUNCTION:    AslDoLineDirective
164 *
165 * PARAMETERS:  None. Uses input() to access current source code line
166 *
167 * RETURN:      Updates global line number and filename
168 *
169 * DESCRIPTION: Handle #line directives emitted by the preprocessor.
170 *
171 * The #line directive is emitted by the preprocesser, and is used to
172 * pass through line numbers from the original source code file to the
173 * preprocessor output file (.i). This allows any compiler-generated
174 * error messages to be displayed with the correct line number.
175 *
176 ******************************************************************************/
177
178static void
179AslDoLineDirective (
180    void)
181{
182    int                     c;
183    char                    *Token;
184    UINT32                  LineNumber;
185    char                    *Filename;
186    UINT32                  i;
187
188   Gbl_HasIncludeFiles = TRUE;
189
190    /* Eat the entire line that contains the #line directive */
191
192    Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
193
194    while ((c = input()) != '\n' && c != EOF)
195    {
196        *Gbl_LineBufPtr = c;
197        Gbl_LineBufPtr++;
198    }
199    *Gbl_LineBufPtr = 0;
200
201    /* First argument is the actual line number */
202
203    Token = strtok (Gbl_CurrentLineBuffer, " ");
204    if (!Token)
205    {
206        goto ResetAndExit;
207    }
208
209    /* First argument is the line number */
210
211    LineNumber = (UINT32) UtDoConstant (Token);
212
213    /* Emit the appropriate number of newlines */
214
215    Gbl_CurrentColumn = 0;
216    if (LineNumber > Gbl_CurrentLineNumber)
217    {
218        for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++)
219        {
220            FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
221            Gbl_CurrentColumn++;
222        }
223    }
224
225    FlSetLineNumber (LineNumber);
226
227    /* Second argument is the optional filename (in double quotes) */
228
229    Token = strtok (NULL, " \"");
230    if (Token)
231    {
232        Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1);
233        strcpy (Filename, Token);
234        FlSetFilename (Filename);
235    }
236
237    /* Third argument is not supported at this time */
238
239ResetAndExit:
240
241    /* Reset globals for a new line */
242
243    Gbl_CurrentLineOffset += Gbl_CurrentColumn;
244    Gbl_CurrentColumn = 0;
245    Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
246}
247
248
249/*******************************************************************************
250 *
251 * FUNCTION:    AslPopInputFileStack
252 *
253 * PARAMETERS:  None
254 *
255 * RETURN:      0 if a node was popped, -1 otherwise
256 *
257 * DESCRIPTION: Pop the top of the input file stack and point the parser to
258 *              the saved parse buffer contained in the fnode. Also, set the
259 *              global line counters to the saved values. This function is
260 *              called when an include file reaches EOF.
261 *
262 ******************************************************************************/
263
264int
265AslPopInputFileStack (
266    void)
267{
268    ASL_FILE_NODE           *Fnode;
269
270
271    Gbl_PreviousIncludeFilename = Gbl_Files[ASL_FILE_INPUT].Filename;
272    Fnode = Gbl_IncludeFileStack;
273    DbgPrint (ASL_PARSE_OUTPUT,
274        "\nPop InputFile Stack, Fnode %p\n", Fnode);
275
276    DbgPrint (ASL_PARSE_OUTPUT,
277        "Include: Closing \"%s\"\n\n", Gbl_Files[ASL_FILE_INPUT].Filename);
278
279    if (!Fnode)
280    {
281        return (-1);
282    }
283
284    /* Close the current include file */
285
286    fclose (yyin);
287
288    /* Update the top-of-stack */
289
290    Gbl_IncludeFileStack = Fnode->Next;
291
292    /* Reset global line counter and filename */
293
294    Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
295    Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
296
297    /* Point the parser to the popped file */
298
299    yy_delete_buffer (YY_CURRENT_BUFFER);
300    yy_switch_to_buffer (Fnode->State);
301
302    /* All done with this node */
303
304    ACPI_FREE (Fnode);
305    return (0);
306}
307
308
309/*******************************************************************************
310 *
311 * FUNCTION:    AslPushInputFileStack
312 *
313 * PARAMETERS:  InputFile           - Open file pointer
314 *              Filename            - Name of the file
315 *
316 * RETURN:      None
317 *
318 * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
319 *              to this file. Called when an include file is successfully
320 *              opened.
321 *
322 ******************************************************************************/
323
324void
325AslPushInputFileStack (
326    FILE                    *InputFile,
327    char                    *Filename)
328{
329    ASL_FILE_NODE           *Fnode;
330    YY_BUFFER_STATE         State;
331
332
333    /* Save the current state in an Fnode */
334
335    Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
336
337    Fnode->File = yyin;
338    Fnode->Next = Gbl_IncludeFileStack;
339    Fnode->State = YY_CURRENT_BUFFER;
340    Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
341    Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;
342
343    /* Push it on the stack */
344
345    Gbl_IncludeFileStack = Fnode;
346
347    /* Point the parser to this file */
348
349    State = yy_create_buffer (InputFile, YY_BUF_SIZE);
350    yy_switch_to_buffer (State);
351
352    DbgPrint (ASL_PARSE_OUTPUT,
353        "\nPush InputFile Stack, returning %p\n\n", InputFile);
354
355    /* Reset the global line count and filename */
356
357    Gbl_Files[ASL_FILE_INPUT].Filename =
358        UtStringCacheCalloc (strlen (Filename) + 1);
359
360    strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
361
362    Gbl_CurrentLineNumber = 1;
363    yyin = InputFile;
364}
365
366
367/*******************************************************************************
368 *
369 * FUNCTION:    AslResetCurrentLineBuffer
370 *
371 * PARAMETERS:  None
372 *
373 * RETURN:      None
374 *
375 * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
376 *
377 ******************************************************************************/
378
379void
380AslResetCurrentLineBuffer (
381    void)
382{
383
384    if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
385    {
386        FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
387            Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
388    }
389
390    Gbl_CurrentLineOffset += Gbl_CurrentColumn;
391    Gbl_CurrentColumn = 0;
392
393    Gbl_CurrentLineNumber++;
394    Gbl_LogicalLineNumber++;
395    Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
396}
397
398
399/*******************************************************************************
400 *
401 * FUNCTION:    AslInsertLineBuffer
402 *
403 * PARAMETERS:  SourceChar          - One char from the input ASL source file
404 *
405 * RETURN:      None
406 *
407 * DESCRIPTION: Put one character of the source file into the temp line buffer
408 *
409 ******************************************************************************/
410
411void
412AslInsertLineBuffer (
413    int                     SourceChar)
414{
415    UINT32                  i;
416    UINT32                  Count = 1;
417
418
419    if (SourceChar == EOF)
420    {
421        return;
422    }
423
424    Gbl_InputByteCount++;
425
426    /* Handle tabs. Convert to spaces */
427
428    if (SourceChar == '\t')
429    {
430        SourceChar = ' ';
431        Count = ASL_SPACES_PER_TAB -
432                    (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
433    }
434
435    for (i = 0; i < Count; i++)
436    {
437        Gbl_CurrentColumn++;
438
439        /* Insert the character into the line buffer */
440
441        *Gbl_LineBufPtr = (UINT8) SourceChar;
442        Gbl_LineBufPtr++;
443
444        if (Gbl_LineBufPtr >
445            (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1)))
446        {
447#if 0
448            /*
449             * Warning if we have split a long source line.
450             * <Probably overkill>
451             */
452            sprintf (MsgBuffer, "Max %u", Gbl_LineBufferSize);
453            AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
454                Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
455                Gbl_CurrentLineOffset, Gbl_CurrentColumn,
456                Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
457#endif
458
459            AslResetCurrentLineBuffer ();
460        }
461        else if (SourceChar == '\n')
462        {
463            /* End of line */
464
465            AslResetCurrentLineBuffer ();
466        }
467    }
468}
469
470
471/*******************************************************************************
472 *
473 * FUNCTION:    count
474 *
475 * PARAMETERS:  yytext              - Contains the matched keyword.
476 *              Type                - Keyword/Character type:
477 *                                      0 = anything except a keyword
478 *                                      1 = pseudo-keywords
479 *                                      2 = non-executable ASL keywords
480 *                                      3 = executable ASL keywords
481 *
482 * RETURN:      None
483 *
484 * DESCRIPTION: Count keywords and put them into the line buffer
485 *
486 ******************************************************************************/
487
488static void
489count (
490    int                 Type)
491{
492    int                 i;
493
494
495    switch (Type)
496    {
497    case 2:
498
499        TotalKeywords++;
500        TotalNamedObjects++;
501        break;
502
503    case 3:
504
505        TotalKeywords++;
506        TotalExecutableOpcodes++;
507        break;
508
509    default:
510
511        break;
512    }
513
514    for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
515    {
516        AslInsertLineBuffer (yytext[i]);
517        *Gbl_LineBufPtr = 0;
518    }
519}
520
521
522/*******************************************************************************
523 *
524 * FUNCTION:    AslDoComment
525 *
526 * PARAMETERS:  none
527 *
528 * RETURN:      none
529 *
530 * DESCRIPTION: Process a standard comment.
531 *
532 ******************************************************************************/
533
534static char
535AslDoComment (
536    void)
537{
538    int                 c;
539    int                 c1 = 0;
540
541
542    AslInsertLineBuffer ('/');
543    AslInsertLineBuffer ('*');
544
545loop:
546
547    /* Eat chars until end-of-comment */
548
549    while (((c = input ()) != '*') && (c != EOF))
550    {
551        AslInsertLineBuffer (c);
552        c1 = c;
553    }
554
555    if (c == EOF)
556    {
557        goto EarlyEOF;
558    }
559
560    /*
561     * Check for nested comment -- can help catch cases where a previous
562     * comment was accidently left unterminated
563     */
564    if ((c1 == '/') && (c == '*'))
565    {
566        AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
567            Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
568            Gbl_InputByteCount, Gbl_CurrentColumn,
569            Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
570    }
571
572    /* Comment is closed only if the NEXT character is a slash */
573
574    AslInsertLineBuffer (c);
575
576    if (((c1 = input ()) != '/') && (c1 != EOF))
577    {
578        unput(c1);
579        goto loop;
580    }
581
582    if (c1 == EOF)
583    {
584        goto EarlyEOF;
585    }
586
587    AslInsertLineBuffer (c1);
588    return (TRUE);
589
590
591EarlyEOF:
592    /*
593     * Premature End-Of-File
594     */
595    AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
596        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
597        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
598        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
599    return (FALSE);
600}
601
602
603/*******************************************************************************
604 *
605 * FUNCTION:    AslDoCommentType2
606 *
607 * PARAMETERS:  none
608 *
609 * RETURN:      none
610 *
611 * DESCRIPTION: Process a new "//" comment.
612 *
613 ******************************************************************************/
614
615static char
616AslDoCommentType2 (
617    void)
618{
619    int                 c;
620
621
622    AslInsertLineBuffer ('/');
623    AslInsertLineBuffer ('/');
624
625    while (((c = input ()) != '\n') && (c != EOF))
626    {
627        AslInsertLineBuffer (c);
628    }
629
630    if (c == EOF)
631    {
632        /* End of file is OK, change to newline. Let parser detect EOF later */
633
634        c = '\n';
635    }
636
637    AslInsertLineBuffer (c);
638    return (TRUE);
639}
640
641
642/*******************************************************************************
643 *
644 * FUNCTION:    AslDoStringLiteral
645 *
646 * PARAMETERS:  none
647 *
648 * RETURN:      none
649 *
650 * DESCRIPTION: Process a string literal (surrounded by quotes)
651 *
652 ******************************************************************************/
653
654static char
655AslDoStringLiteral (
656    void)
657{
658    char                *StringBuffer = MsgBuffer;
659    char                *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
660    char                *CleanString;
661    int                 StringChar;
662    UINT32              State = ASL_NORMAL_CHAR;
663    UINT32              i = 0;
664    UINT8               Digit;
665    char                ConvertBuffer[4];
666
667
668    /*
669     * Eat chars until end-of-literal.
670     * NOTE:  Put back the original surrounding quotes into the
671     * source line buffer.
672     */
673    AslInsertLineBuffer ('\"');
674    while ((StringChar = input()) != EOF)
675    {
676        AslInsertLineBuffer (StringChar);
677
678DoCharacter:
679        switch (State)
680        {
681        case ASL_NORMAL_CHAR:
682
683            switch (StringChar)
684            {
685            case '\\':
686                /*
687                 * Special handling for backslash-escape sequence. We will
688                 * toss the backslash and translate the escape char(s).
689                 */
690                State = ASL_ESCAPE_SEQUENCE;
691                continue;
692
693            case '\"':
694
695                /* String terminator */
696
697                goto CompletedString;
698
699            default:
700
701                break;
702            }
703            break;
704
705
706        case ASL_ESCAPE_SEQUENCE:
707
708            State = ASL_NORMAL_CHAR;
709            switch (StringChar)
710            {
711            case 'a':
712
713                StringChar = 0x07;      /* BELL */
714                break;
715
716            case 'b':
717
718                StringChar = 0x08;      /* BACKSPACE */
719                break;
720
721            case 'f':
722
723                StringChar = 0x0C;      /* FORMFEED */
724                break;
725
726            case 'n':
727
728                StringChar = 0x0A;      /* LINEFEED */
729                break;
730
731            case 'r':
732
733                StringChar = 0x0D;      /* CARRIAGE RETURN*/
734                break;
735
736            case 't':
737
738                StringChar = 0x09;      /* HORIZONTAL TAB */
739                break;
740
741            case 'v':
742
743                StringChar = 0x0B;      /* VERTICAL TAB */
744                break;
745
746            case 'x':
747
748                State = ASL_HEX_CONSTANT;
749                i = 0;
750                continue;
751
752            case '\'':                  /* Single Quote */
753            case '\"':                  /* Double Quote */
754            case '\\':                  /* Backslash */
755
756                break;
757
758            default:
759
760                /* Check for an octal digit (0-7) */
761
762                if (ACPI_IS_OCTAL_DIGIT (StringChar))
763                {
764                    State = ASL_OCTAL_CONSTANT;
765                    ConvertBuffer[0] = StringChar;
766                    i = 1;
767                    continue;
768                }
769
770                /* Unknown escape sequence issue warning, but use the character */
771
772                AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
773                    Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
774                    Gbl_CurrentLineOffset, Gbl_CurrentColumn,
775                    Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
776                break;
777            }
778            break;
779
780
781        case ASL_OCTAL_CONSTANT:
782
783            /* Up to three octal digits allowed */
784
785            if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
786                (i > 2))
787            {
788                /*
789                 * Reached end of the constant. Convert the assembled ASCII
790                 * string and resume processing of the next character
791                 */
792                ConvertBuffer[i] = 0;
793                Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);
794
795                /* Check for NULL or non-ascii character (ignore if so) */
796
797                if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
798                {
799                    AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
800                        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
801                        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
802                        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
803                }
804                else
805                {
806                    *StringBuffer = (char) Digit;
807                    StringBuffer++;
808                    if (StringBuffer >= EndBuffer)
809                    {
810                        goto BufferOverflow;
811                    }
812                }
813
814                State = ASL_NORMAL_CHAR;
815                goto DoCharacter;
816                break;
817            }
818
819            /* Append another digit of the constant */
820
821            ConvertBuffer[i] = StringChar;
822            i++;
823            continue;
824
825        case ASL_HEX_CONSTANT:
826
827            /* Up to two hex digits allowed */
828
829            if (!isxdigit (StringChar) ||
830                (i > 1))
831            {
832                /*
833                 * Reached end of the constant. Convert the assembled ASCII
834                 * string and resume processing of the next character
835                 */
836                ConvertBuffer[i] = 0;
837                Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);
838
839                /* Check for NULL or non-ascii character (ignore if so) */
840
841                if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
842                {
843                    AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
844                        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
845                        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
846                        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
847                }
848                else
849                {
850                    *StringBuffer = (char) Digit;
851                    StringBuffer++;
852                    if (StringBuffer >= EndBuffer)
853                    {
854                        goto BufferOverflow;
855                    }
856                }
857
858                State = ASL_NORMAL_CHAR;
859                goto DoCharacter;
860                break;
861            }
862
863            /* Append another digit of the constant */
864
865            ConvertBuffer[i] = StringChar;
866            i++;
867            continue;
868
869        default:
870
871            break;
872        }
873
874        /* Save the finished character */
875
876        *StringBuffer = StringChar;
877        StringBuffer++;
878        if (StringBuffer >= EndBuffer)
879        {
880            goto BufferOverflow;
881        }
882    }
883
884    /*
885     * Premature End-Of-File
886     */
887    AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
888        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
889        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
890        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
891    return (FALSE);
892
893
894CompletedString:
895    /*
896     * Null terminate the input string and copy string to a new buffer
897     */
898    *StringBuffer = 0;
899
900    CleanString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
901    if (!CleanString)
902    {
903        AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
904            Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
905            Gbl_CurrentLineOffset, Gbl_CurrentColumn,
906            Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
907        return (FALSE);
908    }
909
910    strcpy (CleanString, MsgBuffer);
911    AslCompilerlval.s = CleanString;
912    return (TRUE);
913
914
915BufferOverflow:
916
917    /* Literal was too long */
918
919    AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
920        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
921        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
922        Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
923    return (FALSE);
924}
925