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 - 2023, 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 * Alternatively, you may choose to be licensed under the terms of the
118 * following license:
119 *
120 * Redistribution and use in source and binary forms, with or without
121 * modification, are permitted provided that the following conditions
122 * are met:
123 * 1. Redistributions of source code must retain the above copyright
124 *    notice, this list of conditions, and the following disclaimer,
125 *    without modification.
126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127 *    substantially similar to the "NO WARRANTY" disclaimer below
128 *    ("Disclaimer") and any redistribution must be conditioned upon
129 *    including a substantially similar Disclaimer requirement for further
130 *    binary redistribution.
131 * 3. Neither the names of the above-listed copyright holders nor the names
132 *    of any contributors may be used to endorse or promote products derived
133 *    from this software without specific prior written permission.
134 *
135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 *
147 * Alternatively, you may choose to be licensed under the terms of the
148 * GNU General Public License ("GPL") version 2 as published by the Free
149 * Software Foundation.
150 *
151 *****************************************************************************/
152
153/* Configuration */
154
155#define ASL_SPACES_PER_TAB      4
156
157#define ASL_NORMAL_CHAR         0
158#define ASL_ESCAPE_SEQUENCE     1
159#define ASL_OCTAL_CONSTANT      2
160#define ASL_HEX_CONSTANT        3
161
162
163void
164yyerror (char const *s)
165{
166
167  AcpiOsPrintf ("YYERROR: %s\n", s);
168}
169
170
171/*******************************************************************************
172 *
173 * FUNCTION:    AslParserCleanup
174 *
175 * Used to delete the current buffer
176 *
177 ******************************************************************************/
178
179void
180AslParserCleanup (
181    void)
182{
183
184    yy_delete_buffer (YY_CURRENT_BUFFER);
185}
186
187
188/*******************************************************************************
189 *
190 * FUNCTION:    AslDoLineDirective
191 *
192 * PARAMETERS:  None. Uses input() to access current source code line
193 *
194 * RETURN:      Updates global line number and filename
195 *
196 * DESCRIPTION: Handle #line directives emitted by the preprocessor.
197 *
198 * The #line directive is emitted by the preprocessor, and is used to
199 * pass through line numbers from the original source code file to the
200 * preprocessor output file (.i). This allows any compiler-generated
201 * error messages to be displayed with the correct line number.
202 *
203 ******************************************************************************/
204
205static void
206AslDoLineDirective (
207    void)
208{
209    int                     c;
210    char                    *Token;
211    UINT32                  LineNumber;
212    char                    *Filename;
213    UINT32                  i;
214
215   AslGbl_HasIncludeFiles = TRUE;
216
217    /* Eat the entire line that contains the #line directive */
218
219    AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer;
220
221    while ((c = input()) != '\n' && c != EOF)
222    {
223        *AslGbl_LineBufPtr = (char) c;
224        AslGbl_LineBufPtr++;
225    }
226    *AslGbl_LineBufPtr = 0;
227
228    /* First argument is the actual line number */
229
230    Token = strtok (AslGbl_CurrentLineBuffer, " ");
231    if (!Token)
232    {
233        goto ResetAndExit;
234    }
235
236    /* First argument is the line number */
237
238    LineNumber = (UINT32) UtDoConstant (Token);
239
240    /* Emit the appropriate number of newlines */
241
242    AslGbl_CurrentColumn = 0;
243    if (LineNumber > AslGbl_CurrentLineNumber)
244    {
245        for (i = 0; i < (LineNumber - AslGbl_CurrentLineNumber); i++)
246        {
247            FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
248            AslGbl_CurrentColumn++;
249        }
250    }
251
252    FlSetLineNumber (LineNumber);
253
254    /* Second argument is the optional filename (in double quotes) */
255
256    Token = strtok (NULL, " \"");
257    if (Token)
258    {
259        Filename = UtLocalCacheCalloc (strlen (Token) + 1);
260        strcpy (Filename, Token);
261        FlSetFilename (Filename);
262    }
263
264    /* Third argument is not supported at this time */
265
266ResetAndExit:
267
268    /* Reset globals for a new line */
269
270    AslGbl_CurrentLineOffset += AslGbl_CurrentColumn;
271    AslGbl_CurrentColumn = 0;
272    AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer;
273}
274
275
276/*******************************************************************************
277 *
278 * FUNCTION:    AslPopInputFileStack
279 *
280 * PARAMETERS:  None
281 *
282 * RETURN:      0 if a node was popped, -1 otherwise
283 *
284 * DESCRIPTION: Pop the top of the input file stack and point the parser to
285 *              the saved parse buffer contained in the fnode. Also, set the
286 *              global line counters to the saved values. This function is
287 *              called when an include file reaches EOF.
288 *
289 ******************************************************************************/
290
291int
292AslPopInputFileStack (
293    void)
294{
295    ASL_FILE_NODE           *Fnode;
296
297
298    AslGbl_PreviousIncludeFilename = AslGbl_Files[ASL_FILE_INPUT].Filename;
299    Fnode = AslGbl_IncludeFileStack;
300    DbgPrint (ASL_PARSE_OUTPUT,
301        "\nPop InputFile Stack, Fnode %p\n", Fnode);
302
303    DbgPrint (ASL_PARSE_OUTPUT,
304        "Include: Closing \"%s\"\n\n", AslGbl_Files[ASL_FILE_INPUT].Filename);
305
306    if (!Fnode)
307    {
308        return (-1);
309    }
310
311    /* Close the current include file */
312
313    fclose (yyin);
314
315    /* Update the top-of-stack */
316
317    AslGbl_IncludeFileStack = Fnode->Next;
318
319    /* Reset global line counter and filename */
320
321    AslGbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
322    AslGbl_CurrentLineNumber = Fnode->CurrentLineNumber;
323
324    /* Point the parser to the popped file */
325
326    yy_delete_buffer (YY_CURRENT_BUFFER);
327    yy_switch_to_buffer (Fnode->State);
328
329    /* All done with this node */
330
331    ACPI_FREE (Fnode);
332    return (0);
333}
334
335
336/*******************************************************************************
337 *
338 * FUNCTION:    AslPushInputFileStack
339 *
340 * PARAMETERS:  InputFile           - Open file pointer
341 *              Filename            - Name of the file
342 *
343 * RETURN:      None
344 *
345 * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
346 *              to this file. Called when an include file is successfully
347 *              opened.
348 *
349 ******************************************************************************/
350
351void
352AslPushInputFileStack (
353    FILE                    *InputFile,
354    char                    *Filename)
355{
356    ASL_FILE_NODE           *Fnode;
357    YY_BUFFER_STATE         State;
358
359
360    /* Save the current state in an Fnode */
361
362    Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
363
364    Fnode->File = yyin;
365    Fnode->Next = AslGbl_IncludeFileStack;
366    Fnode->State = YY_CURRENT_BUFFER;
367    Fnode->Filename = AslGbl_Files[ASL_FILE_INPUT].Filename;
368    Fnode->CurrentLineNumber = AslGbl_CurrentLineNumber;
369
370    /* Push it on the stack */
371
372    AslGbl_IncludeFileStack = Fnode;
373
374    /* Point the parser to this file */
375
376    State = yy_create_buffer (InputFile, YY_BUF_SIZE);
377    yy_switch_to_buffer (State);
378
379    DbgPrint (ASL_PARSE_OUTPUT,
380        "\nPush InputFile Stack, returning %p\n\n", InputFile);
381
382    /* Reset the global line count and filename */
383
384    AslGbl_Files[ASL_FILE_INPUT].Filename =
385        UtLocalCacheCalloc (strlen (Filename) + 1);
386
387    strcpy (AslGbl_Files[ASL_FILE_INPUT].Filename, Filename);
388
389    AslGbl_CurrentLineNumber = 1;
390    yyin = InputFile;
391
392    /* converter: reset the comment state to STANDARD_COMMENT */
393
394    AslGbl_CommentState.CommentType = STANDARD_COMMENT;
395}
396
397
398/*******************************************************************************
399 *
400 * FUNCTION:    AslResetCurrentLineBuffer
401 *
402 * PARAMETERS:  None
403 *
404 * RETURN:      None
405 *
406 * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
407 *
408 ******************************************************************************/
409
410void
411AslResetCurrentLineBuffer (
412    void)
413{
414
415    if (AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
416    {
417        FlWriteFile (ASL_FILE_SOURCE_OUTPUT, AslGbl_CurrentLineBuffer,
418            AslGbl_LineBufPtr - AslGbl_CurrentLineBuffer);
419    }
420
421    AslGbl_CurrentLineOffset += AslGbl_CurrentColumn;
422    AslGbl_CurrentColumn = 0;
423
424    AslGbl_CurrentLineNumber++;
425    AslGbl_LogicalLineNumber++;
426    AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer;
427}
428
429
430/*******************************************************************************
431 *
432 * FUNCTION:    AslInsertLineBuffer
433 *
434 * PARAMETERS:  SourceChar          - One char from the input ASL source file
435 *
436 * RETURN:      None
437 *
438 * DESCRIPTION: Put one character of the source file into the temp line buffer
439 *
440 ******************************************************************************/
441
442void
443AslInsertLineBuffer (
444    int                     SourceChar)
445{
446    UINT32                  i;
447    UINT32                  Count = 1;
448
449
450    if (SourceChar == EOF)
451    {
452        return;
453    }
454
455    AslGbl_InputByteCount++;
456
457    /* Handle tabs. Convert to spaces */
458
459    if (SourceChar == '\t')
460    {
461        SourceChar = ' ';
462        Count = ASL_SPACES_PER_TAB -
463                    (AslGbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
464    }
465
466    for (i = 0; i < Count; i++)
467    {
468        AslGbl_CurrentColumn++;
469
470        /* Insert the character into the line buffer */
471
472        *AslGbl_LineBufPtr = (UINT8) SourceChar;
473        AslGbl_LineBufPtr++;
474
475        if (AslGbl_LineBufPtr >
476            (AslGbl_CurrentLineBuffer + (AslGbl_LineBufferSize - 1)))
477        {
478#if 0
479            /*
480             * Warning if we have split a long source line.
481             * <Probably overkill>
482             */
483            sprintf (MsgBuffer, "Max %u", AslGbl_LineBufferSize);
484            AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
485                AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
486                AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
487                AslGbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
488#endif
489
490            AslResetCurrentLineBuffer ();
491        }
492        else if (SourceChar == '\n')
493        {
494            /* End of line */
495
496            AslResetCurrentLineBuffer ();
497        }
498
499        if (AcpiGbl_CaptureComments)
500        {
501            CvProcessCommentState ((char) SourceChar);
502        }
503    }
504}
505
506
507/*******************************************************************************
508 *
509 * FUNCTION:    count
510 *
511 * PARAMETERS:  yytext              - Contains the matched keyword.
512 *              Type                - Keyword/Character type:
513 *                                      0 = anything except a keyword
514 *                                      1 = pseudo-keywords
515 *                                      2 = non-executable ASL keywords
516 *                                      3 = executable ASL keywords
517 *
518 * RETURN:      None
519 *
520 * DESCRIPTION: Count keywords and put them into the line buffer
521 *
522 ******************************************************************************/
523
524static void
525count (
526    int                 Type)
527{
528    char                *p;
529
530
531    switch (Type)
532    {
533    case 2:
534
535        ++AslGbl_TotalKeywords;
536        ++AslGbl_TotalNamedObjects;
537        ++AslGbl_FilesList->TotalKeywords;
538        ++AslGbl_FilesList->TotalNamedObjects;
539        break;
540
541    case 3:
542
543        ++AslGbl_TotalKeywords;
544        ++AslGbl_TotalExecutableOpcodes;
545        ++AslGbl_FilesList->TotalKeywords;
546        ++AslGbl_FilesList->TotalExecutableOpcodes;
547        break;
548
549    default:
550
551        break;
552    }
553
554    for (p = yytext; *p != '\0'; p++)
555    {
556        AslInsertLineBuffer (*p);
557        *AslGbl_LineBufPtr = 0;
558    }
559}
560
561
562/*******************************************************************************
563 *
564 * FUNCTION:    AslDoComment
565 *
566 * PARAMETERS:  none
567 *
568 * RETURN:      none
569 *
570 * DESCRIPTION: Process a standard comment.
571 *
572 ******************************************************************************/
573
574static BOOLEAN
575AslDoComment (
576    void)
577{
578    int                     c;
579    int                     c1 = 0;
580    char                    *StringBuffer = AslGbl_MsgBuffer;
581    char                    *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
582    ASL_COMMENT_STATE       CurrentState = AslGbl_CommentState; /* to reference later on */
583
584
585    AslInsertLineBuffer ('/');
586    AslInsertLineBuffer ('*');
587    if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
588    {
589        *StringBuffer = '/';
590        ++StringBuffer;
591        *StringBuffer = '*';
592        ++StringBuffer;
593    }
594
595loop:
596
597    /* Eat chars until end-of-comment */
598
599    while (((c = input ()) != '*') && (c != EOF))
600    {
601        AslInsertLineBuffer (c);
602        if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
603        {
604            *StringBuffer = (char) c;
605            ++StringBuffer;
606        }
607        c1 = c;
608    }
609
610    if (c == EOF)
611    {
612        goto EarlyEOF;
613    }
614
615    /*
616     * Check for nested comment -- can help catch cases where a previous
617     * comment was accidentally left unterminated
618     */
619    if ((c1 == '/') && (c == '*'))
620    {
621        AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
622            AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
623            AslGbl_InputByteCount, AslGbl_CurrentColumn,
624            AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
625    }
626
627    /* Comment is closed only if the NEXT character is a slash */
628
629    AslInsertLineBuffer (c);
630    if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
631    {
632        *StringBuffer = (char) c;
633        ++StringBuffer;
634    }
635
636    if (((c1 = input ()) != '/') && (c1 != EOF))
637    {
638        unput (c1);
639        goto loop;
640    }
641
642    if (c1 == EOF)
643    {
644        goto EarlyEOF;
645    }
646    if (StringBuffer > EndBuffer)
647    {
648        goto BufferOverflow;
649    }
650
651    AslInsertLineBuffer (c1);
652    CvProcessComment (CurrentState, StringBuffer, c1);
653    return (TRUE);
654
655
656EarlyEOF:
657    /*
658     * Premature End-Of-File
659     */
660    AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
661        AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
662        AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
663        AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
664    return (FALSE);
665
666
667BufferOverflow:
668
669    /* Comment was too long */
670
671    AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
672        AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
673        AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
674        AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
675    return (FALSE);
676
677}
678
679
680/*******************************************************************************
681 *
682 * FUNCTION:    AslDoCommentType2
683 *
684 * PARAMETERS:  none
685 *
686 * RETURN:      none
687 *
688 * DESCRIPTION: Process a new "//" comment. Inline comments will be converted
689 *              to "/ *" standard comments.
690 *
691 ******************************************************************************/
692
693static BOOLEAN
694AslDoCommentType2 (
695    void)
696{
697    int                     c;
698    char                    *StringBuffer = AslGbl_MsgBuffer;
699    char                    *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
700    ASL_COMMENT_STATE       CurrentState = AslGbl_CommentState;
701
702
703    AslInsertLineBuffer ('/');
704
705    if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
706    {
707        AslInsertLineBuffer ('*');
708        *StringBuffer = '/';
709        ++StringBuffer;
710        *StringBuffer = '*';
711        ++StringBuffer;
712    }
713    else
714    {
715        AslInsertLineBuffer ('/');
716    }
717
718    while (((c = input ()) != '\n') && (c != EOF))
719    {
720        AslInsertLineBuffer (c);
721        if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
722        {
723            *StringBuffer = (char) c;
724            ++StringBuffer;
725        }
726    }
727
728    if (c == EOF)
729    {
730        /* End of file is OK, change to newline. Let parser detect EOF later */
731
732        c = '\n';
733    }
734
735    if (StringBuffer > EndBuffer)
736    {
737        goto BufferOverflow;
738    }
739    AslInsertLineBuffer (c);
740
741    CvProcessCommentType2 (CurrentState, StringBuffer);
742    return (TRUE);
743
744
745BufferOverflow:
746
747    /* Comment was too long */
748
749    AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
750        AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
751        AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
752        AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
753    return (FALSE);
754
755}
756
757
758/*******************************************************************************
759 *
760 * FUNCTION:    AslDoStringLiteral
761 *
762 * PARAMETERS:  none
763 *
764 * RETURN:      none
765 *
766 * DESCRIPTION: Process a string literal (surrounded by quotes)
767 *
768 ******************************************************************************/
769
770static char
771AslDoStringLiteral (
772    void)
773{
774    char                *StringBuffer = AslGbl_MsgBuffer;
775    char                *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
776    char                *CleanString;
777    int                 StringChar;
778    UINT32              State = ASL_NORMAL_CHAR;
779    UINT32              i = 0;
780    UINT8               Digit;
781    char                ConvertBuffer[4];
782
783
784    /*
785     * Eat chars until end-of-literal.
786     * NOTE:  Put back the original surrounding quotes into the
787     * source line buffer.
788     */
789    AslInsertLineBuffer ('\"');
790    while ((StringChar = input()) != EOF)
791    {
792        AslInsertLineBuffer (StringChar);
793
794DoCharacter:
795        switch (State)
796        {
797        case ASL_NORMAL_CHAR:
798
799            switch (StringChar)
800            {
801            case '\\':
802                /*
803                 * Special handling for backslash-escape sequence. We will
804                 * toss the backslash and translate the escape char(s).
805                 */
806                State = ASL_ESCAPE_SEQUENCE;
807                continue;
808
809            case '\"':
810
811                /* String terminator */
812
813                goto CompletedString;
814
815            default:
816
817                break;
818            }
819            break;
820
821
822        case ASL_ESCAPE_SEQUENCE:
823
824            State = ASL_NORMAL_CHAR;
825            switch (StringChar)
826            {
827            case 'a':
828
829                StringChar = 0x07;      /* BELL */
830                break;
831
832            case 'b':
833
834                StringChar = 0x08;      /* BACKSPACE */
835                break;
836
837            case 'f':
838
839                StringChar = 0x0C;      /* FORMFEED */
840                break;
841
842            case 'n':
843
844                StringChar = 0x0A;      /* LINEFEED */
845                break;
846
847            case 'r':
848
849                StringChar = 0x0D;      /* CARRIAGE RETURN*/
850                break;
851
852            case 't':
853
854                StringChar = 0x09;      /* HORIZONTAL TAB */
855                break;
856
857            case 'v':
858
859                StringChar = 0x0B;      /* VERTICAL TAB */
860                break;
861
862            case 'x':
863
864                State = ASL_HEX_CONSTANT;
865                i = 0;
866                continue;
867
868            case '\'':                  /* Single Quote */
869            case '\"':                  /* Double Quote */
870            case '\\':                  /* Backslash */
871
872                break;
873
874            default:
875
876                /* Check for an octal digit (0-7) */
877
878                if (ACPI_IS_OCTAL_DIGIT (StringChar))
879                {
880                    State = ASL_OCTAL_CONSTANT;
881                    ConvertBuffer[0] = (char) StringChar;
882                    i = 1;
883                    continue;
884                }
885
886                /* Unknown escape sequence issue warning, but use the character */
887
888                AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
889                    AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
890                    AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
891                    AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
892                break;
893            }
894            break;
895
896
897        case ASL_OCTAL_CONSTANT:
898
899            /* Up to three octal digits allowed */
900
901            if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
902                (i > 2))
903            {
904                /*
905                 * Reached end of the constant. Convert the assembled ASCII
906                 * string and resume processing of the next character
907                 */
908                ConvertBuffer[i] = 0;
909                Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);
910
911                /* Check for NULL or non-ascii character (ignore if so) */
912
913                if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
914                {
915                    AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
916                        AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
917                        AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
918                        AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
919                }
920                else
921                {
922                    *StringBuffer = (char) Digit;
923                    StringBuffer++;
924                    if (StringBuffer >= EndBuffer)
925                    {
926                        goto BufferOverflow;
927                    }
928                }
929
930                State = ASL_NORMAL_CHAR;
931                goto DoCharacter;
932                break;
933            }
934
935            /* Append another digit of the constant */
936
937            ConvertBuffer[i] = (char) StringChar;
938            i++;
939            continue;
940
941        case ASL_HEX_CONSTANT:
942
943            /* Up to two hex digits allowed */
944
945            if (!isxdigit (StringChar) ||
946                (i > 1))
947            {
948                /*
949                 * Reached end of the constant. Convert the assembled ASCII
950                 * string and resume processing of the next character
951                 */
952                ConvertBuffer[i] = 0;
953                Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);
954
955                /* Check for NULL or non-ascii character (ignore if so) */
956
957                if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
958                {
959                    AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
960                        AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
961                        AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
962                        AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
963                }
964                else
965                {
966                    *StringBuffer = (char) Digit;
967                    StringBuffer++;
968                    if (StringBuffer >= EndBuffer)
969                    {
970                        goto BufferOverflow;
971                    }
972                }
973
974                State = ASL_NORMAL_CHAR;
975                goto DoCharacter;
976                break;
977            }
978
979            /* Append another digit of the constant */
980
981            ConvertBuffer[i] = (char) StringChar;
982            i++;
983            continue;
984
985        default:
986
987            break;
988        }
989
990        /* Save the finished character */
991
992        *StringBuffer = (char) StringChar;
993        StringBuffer++;
994        if (StringBuffer >= EndBuffer)
995        {
996            goto BufferOverflow;
997        }
998    }
999
1000    /*
1001     * Premature End-Of-File
1002     */
1003    AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
1004        AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
1005        AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
1006        AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
1007    return (FALSE);
1008
1009
1010CompletedString:
1011    /*
1012     * Null terminate the input string and copy string to a new buffer
1013     */
1014    *StringBuffer = 0;
1015
1016    CleanString = UtLocalCacheCalloc (strlen (AslGbl_MsgBuffer) + 1);
1017    strcpy (CleanString, AslGbl_MsgBuffer);
1018    AslCompilerlval.s = CleanString;
1019    return (TRUE);
1020
1021
1022BufferOverflow:
1023
1024    /* Literal was too long */
1025
1026    AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
1027        AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
1028        AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
1029        AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
1030    return (FALSE);
1031}
1032