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