xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslsupport.l (revision 2c7d7e3ca2e4f0b675c6c58e614f6aede66c678e)
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
yyerror(char const * s)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
AslParserCleanup(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
AslDoLineDirective(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
AslPopInputFileStack(void)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
AslPushInputFileStack(FILE * InputFile,char * Filename)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
AslResetCurrentLineBuffer(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
AslInsertLineBuffer(int SourceChar)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
count(int Type)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
AslDoComment(void)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
AslDoCommentType2(void)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
AslDoStringLiteral(void)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