xref: /freebsd/sys/contrib/dev/acpica/compiler/aslsupport.l (revision fed1ca4b719c56c930f2259d80663cd34be812bb)
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 - 2016, 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 /* File node - used for "Include" operator file stack */
56 
57 typedef struct asl_file_node
58 {
59     FILE                    *File;
60     UINT32                  CurrentLineNumber;
61     YY_BUFFER_STATE         State;
62     char                    *Filename;
63     struct asl_file_node    *Next;
64 
65 } ASL_FILE_NODE;
66 
67 /* File stack for the "Include" operator (NOT #include operator) */
68 
69 ASL_FILE_NODE               *Gbl_IncludeFileStack = NULL;
70 
71 
72 /*******************************************************************************
73  *
74  * FUNCTION:    AslParserCleanup
75  *
76  * Used to delete the current buffer
77  *
78  ******************************************************************************/
79 
80 void
81 AslParserCleanup (
82     void)
83 {
84 
85     yy_delete_buffer (YY_CURRENT_BUFFER);
86 }
87 
88 
89 /*******************************************************************************
90  *
91  * FUNCTION:    AslDoLineDirective
92  *
93  * PARAMETERS:  None. Uses input() to access current source code line
94  *
95  * RETURN:      Updates global line number and filename
96  *
97  * DESCRIPTION: Handle #line directives emitted by the preprocessor.
98  *
99  * The #line directive is emitted by the preprocesser, and is used to
100  * pass through line numbers from the original source code file to the
101  * preprocessor output file (.i). This allows any compiler-generated
102  * error messages to be displayed with the correct line number.
103  *
104  ******************************************************************************/
105 
106 static void
107 AslDoLineDirective (
108     void)
109 {
110     int                     c;
111     char                    *Token;
112     UINT32                  LineNumber;
113     char                    *Filename;
114     UINT32                  i;
115 
116    Gbl_HasIncludeFiles = TRUE;
117 
118     /* Eat the entire line that contains the #line directive */
119 
120     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
121 
122     while ((c = input()) != '\n' && c != EOF)
123     {
124         *Gbl_LineBufPtr = c;
125         Gbl_LineBufPtr++;
126     }
127     *Gbl_LineBufPtr = 0;
128 
129     /* First argument is the actual line number */
130 
131     Token = strtok (Gbl_CurrentLineBuffer, " ");
132     if (!Token)
133     {
134         goto ResetAndExit;
135     }
136 
137     /* First argument is the line number */
138 
139     LineNumber = (UINT32) UtDoConstant (Token);
140 
141     /* Emit the appropriate number of newlines */
142 
143     Gbl_CurrentColumn = 0;
144     if (LineNumber > Gbl_CurrentLineNumber)
145     {
146         for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++)
147         {
148             FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
149             Gbl_CurrentColumn++;
150         }
151     }
152 
153     FlSetLineNumber (LineNumber);
154 
155     /* Second argument is the optional filename (in double quotes) */
156 
157     Token = strtok (NULL, " \"");
158     if (Token)
159     {
160         Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1);
161         strcpy (Filename, Token);
162         FlSetFilename (Filename);
163     }
164 
165     /* Third argument is not supported at this time */
166 
167 ResetAndExit:
168 
169     /* Reset globals for a new line */
170 
171     Gbl_CurrentLineOffset += Gbl_CurrentColumn;
172     Gbl_CurrentColumn = 0;
173     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
174 }
175 
176 
177 /*******************************************************************************
178  *
179  * FUNCTION:    AslPopInputFileStack
180  *
181  * PARAMETERS:  None
182  *
183  * RETURN:      0 if a node was popped, -1 otherwise
184  *
185  * DESCRIPTION: Pop the top of the input file stack and point the parser to
186  *              the saved parse buffer contained in the fnode. Also, set the
187  *              global line counters to the saved values. This function is
188  *              called when an include file reaches EOF.
189  *
190  ******************************************************************************/
191 
192 int
193 AslPopInputFileStack (
194     void)
195 {
196     ASL_FILE_NODE           *Fnode;
197 
198 
199     Gbl_PreviousIncludeFilename = Gbl_Files[ASL_FILE_INPUT].Filename;
200     Fnode = Gbl_IncludeFileStack;
201     DbgPrint (ASL_PARSE_OUTPUT,
202         "\nPop InputFile Stack, Fnode %p\n", Fnode);
203 
204     DbgPrint (ASL_PARSE_OUTPUT,
205         "Include: Closing \"%s\"\n\n", Gbl_Files[ASL_FILE_INPUT].Filename);
206 
207     if (!Fnode)
208     {
209         return (-1);
210     }
211 
212     /* Close the current include file */
213 
214     fclose (yyin);
215 
216     /* Update the top-of-stack */
217 
218     Gbl_IncludeFileStack = Fnode->Next;
219 
220     /* Reset global line counter and filename */
221 
222     Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
223     Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
224 
225     /* Point the parser to the popped file */
226 
227     yy_delete_buffer (YY_CURRENT_BUFFER);
228     yy_switch_to_buffer (Fnode->State);
229 
230     /* All done with this node */
231 
232     ACPI_FREE (Fnode);
233     return (0);
234 }
235 
236 
237 /*******************************************************************************
238  *
239  * FUNCTION:    AslPushInputFileStack
240  *
241  * PARAMETERS:  InputFile           - Open file pointer
242  *              Filename            - Name of the file
243  *
244  * RETURN:      None
245  *
246  * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
247  *              to this file. Called when an include file is successfully
248  *              opened.
249  *
250  ******************************************************************************/
251 
252 void
253 AslPushInputFileStack (
254     FILE                    *InputFile,
255     char                    *Filename)
256 {
257     ASL_FILE_NODE           *Fnode;
258     YY_BUFFER_STATE         State;
259 
260 
261     /* Save the current state in an Fnode */
262 
263     Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
264 
265     Fnode->File = yyin;
266     Fnode->Next = Gbl_IncludeFileStack;
267     Fnode->State = YY_CURRENT_BUFFER;
268     Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
269     Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;
270 
271     /* Push it on the stack */
272 
273     Gbl_IncludeFileStack = Fnode;
274 
275     /* Point the parser to this file */
276 
277     State = yy_create_buffer (InputFile, YY_BUF_SIZE);
278     yy_switch_to_buffer (State);
279 
280     DbgPrint (ASL_PARSE_OUTPUT,
281         "\nPush InputFile Stack, returning %p\n\n", InputFile);
282 
283     /* Reset the global line count and filename */
284 
285     Gbl_Files[ASL_FILE_INPUT].Filename =
286         UtStringCacheCalloc (strlen (Filename) + 1);
287 
288     strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
289 
290     Gbl_CurrentLineNumber = 1;
291     yyin = InputFile;
292 }
293 
294 
295 /*******************************************************************************
296  *
297  * FUNCTION:    AslResetCurrentLineBuffer
298  *
299  * PARAMETERS:  None
300  *
301  * RETURN:      None
302  *
303  * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
304  *
305  ******************************************************************************/
306 
307 void
308 AslResetCurrentLineBuffer (
309     void)
310 {
311 
312     if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
313     {
314         FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
315             Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
316     }
317 
318     Gbl_CurrentLineOffset += Gbl_CurrentColumn;
319     Gbl_CurrentColumn = 0;
320 
321     Gbl_CurrentLineNumber++;
322     Gbl_LogicalLineNumber++;
323     Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
324 }
325 
326 
327 /*******************************************************************************
328  *
329  * FUNCTION:    AslInsertLineBuffer
330  *
331  * PARAMETERS:  SourceChar          - One char from the input ASL source file
332  *
333  * RETURN:      None
334  *
335  * DESCRIPTION: Put one character of the source file into the temp line buffer
336  *
337  ******************************************************************************/
338 
339 void
340 AslInsertLineBuffer (
341     int                     SourceChar)
342 {
343     UINT32                  i;
344     UINT32                  Count = 1;
345 
346 
347     if (SourceChar == EOF)
348     {
349         return;
350     }
351 
352     Gbl_InputByteCount++;
353 
354     /* Handle tabs. Convert to spaces */
355 
356     if (SourceChar == '\t')
357     {
358         SourceChar = ' ';
359         Count = ASL_SPACES_PER_TAB -
360                     (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
361     }
362 
363     for (i = 0; i < Count; i++)
364     {
365         Gbl_CurrentColumn++;
366 
367         /* Insert the character into the line buffer */
368 
369         *Gbl_LineBufPtr = (UINT8) SourceChar;
370         Gbl_LineBufPtr++;
371 
372         if (Gbl_LineBufPtr >
373             (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1)))
374         {
375 #if 0
376             /*
377              * Warning if we have split a long source line.
378              * <Probably overkill>
379              */
380             sprintf (MsgBuffer, "Max %u", Gbl_LineBufferSize);
381             AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
382                 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
383                 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
384                 Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
385 #endif
386 
387             AslResetCurrentLineBuffer ();
388         }
389         else if (SourceChar == '\n')
390         {
391             /* End of line */
392 
393             AslResetCurrentLineBuffer ();
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     int                 i;
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 (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
443     {
444         AslInsertLineBuffer (yytext[i]);
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 char
463 AslDoComment (
464     void)
465 {
466     int                 c;
467     int                 c1 = 0;
468 
469 
470     AslInsertLineBuffer ('/');
471     AslInsertLineBuffer ('*');
472 
473 loop:
474 
475     /* Eat chars until end-of-comment */
476 
477     while (((c = input ()) != '*') && (c != EOF))
478     {
479         AslInsertLineBuffer (c);
480         c1 = c;
481     }
482 
483     if (c == EOF)
484     {
485         goto EarlyEOF;
486     }
487 
488     /*
489      * Check for nested comment -- can help catch cases where a previous
490      * comment was accidently left unterminated
491      */
492     if ((c1 == '/') && (c == '*'))
493     {
494         AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
495             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
496             Gbl_InputByteCount, Gbl_CurrentColumn,
497             Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
498     }
499 
500     /* Comment is closed only if the NEXT character is a slash */
501 
502     AslInsertLineBuffer (c);
503 
504     if (((c1 = input ()) != '/') && (c1 != EOF))
505     {
506         unput(c1);
507         goto loop;
508     }
509 
510     if (c1 == EOF)
511     {
512         goto EarlyEOF;
513     }
514 
515     AslInsertLineBuffer (c1);
516     return (TRUE);
517 
518 
519 EarlyEOF:
520     /*
521      * Premature End-Of-File
522      */
523     AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
524         Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
525         Gbl_CurrentLineOffset, Gbl_CurrentColumn,
526         Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
527     return (FALSE);
528 }
529 
530 
531 /*******************************************************************************
532  *
533  * FUNCTION:    AslDoCommentType2
534  *
535  * PARAMETERS:  none
536  *
537  * RETURN:      none
538  *
539  * DESCRIPTION: Process a new "//" comment.
540  *
541  ******************************************************************************/
542 
543 static char
544 AslDoCommentType2 (
545     void)
546 {
547     int                 c;
548 
549 
550     AslInsertLineBuffer ('/');
551     AslInsertLineBuffer ('/');
552 
553     while (((c = input ()) != '\n') && (c != EOF))
554     {
555         AslInsertLineBuffer (c);
556     }
557 
558     if (c == EOF)
559     {
560         /* End of file is OK, change to newline. Let parser detect EOF later */
561 
562         c = '\n';
563     }
564 
565     AslInsertLineBuffer (c);
566     return (TRUE);
567 }
568 
569 
570 /*******************************************************************************
571  *
572  * FUNCTION:    AslDoStringLiteral
573  *
574  * PARAMETERS:  none
575  *
576  * RETURN:      none
577  *
578  * DESCRIPTION: Process a string literal (surrounded by quotes)
579  *
580  ******************************************************************************/
581 
582 static char
583 AslDoStringLiteral (
584     void)
585 {
586     char                *StringBuffer = MsgBuffer;
587     char                *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
588     char                *CleanString;
589     int                 StringChar;
590     UINT32              State = ASL_NORMAL_CHAR;
591     UINT32              i = 0;
592     UINT8               Digit;
593     char                ConvertBuffer[4];
594 
595 
596     /*
597      * Eat chars until end-of-literal.
598      * NOTE:  Put back the original surrounding quotes into the
599      * source line buffer.
600      */
601     AslInsertLineBuffer ('\"');
602     while ((StringChar = input()) != EOF)
603     {
604         AslInsertLineBuffer (StringChar);
605 
606 DoCharacter:
607         switch (State)
608         {
609         case ASL_NORMAL_CHAR:
610 
611             switch (StringChar)
612             {
613             case '\\':
614                 /*
615                  * Special handling for backslash-escape sequence. We will
616                  * toss the backslash and translate the escape char(s).
617                  */
618                 State = ASL_ESCAPE_SEQUENCE;
619                 continue;
620 
621             case '\"':
622 
623                 /* String terminator */
624 
625                 goto CompletedString;
626 
627             default:
628 
629                 break;
630             }
631             break;
632 
633 
634         case ASL_ESCAPE_SEQUENCE:
635 
636             State = ASL_NORMAL_CHAR;
637             switch (StringChar)
638             {
639             case 'a':
640 
641                 StringChar = 0x07;      /* BELL */
642                 break;
643 
644             case 'b':
645 
646                 StringChar = 0x08;      /* BACKSPACE */
647                 break;
648 
649             case 'f':
650 
651                 StringChar = 0x0C;      /* FORMFEED */
652                 break;
653 
654             case 'n':
655 
656                 StringChar = 0x0A;      /* LINEFEED */
657                 break;
658 
659             case 'r':
660 
661                 StringChar = 0x0D;      /* CARRIAGE RETURN*/
662                 break;
663 
664             case 't':
665 
666                 StringChar = 0x09;      /* HORIZONTAL TAB */
667                 break;
668 
669             case 'v':
670 
671                 StringChar = 0x0B;      /* VERTICAL TAB */
672                 break;
673 
674             case 'x':
675 
676                 State = ASL_HEX_CONSTANT;
677                 i = 0;
678                 continue;
679 
680             case '\'':                  /* Single Quote */
681             case '\"':                  /* Double Quote */
682             case '\\':                  /* Backslash */
683 
684                 break;
685 
686             default:
687 
688                 /* Check for an octal digit (0-7) */
689 
690                 if (ACPI_IS_OCTAL_DIGIT (StringChar))
691                 {
692                     State = ASL_OCTAL_CONSTANT;
693                     ConvertBuffer[0] = StringChar;
694                     i = 1;
695                     continue;
696                 }
697 
698                 /* Unknown escape sequence issue warning, but use the character */
699 
700                 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
701                     Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
702                     Gbl_CurrentLineOffset, Gbl_CurrentColumn,
703                     Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
704                 break;
705             }
706             break;
707 
708 
709         case ASL_OCTAL_CONSTANT:
710 
711             /* Up to three octal digits allowed */
712 
713             if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
714                 (i > 2))
715             {
716                 /*
717                  * Reached end of the constant. Convert the assembled ASCII
718                  * string and resume processing of the next character
719                  */
720                 ConvertBuffer[i] = 0;
721                 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);
722 
723                 /* Check for NULL or non-ascii character (ignore if so) */
724 
725                 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
726                 {
727                     AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
728                         Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
729                         Gbl_CurrentLineOffset, Gbl_CurrentColumn,
730                         Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
731                 }
732                 else
733                 {
734                     *StringBuffer = (char) Digit;
735                     StringBuffer++;
736                     if (StringBuffer >= EndBuffer)
737                     {
738                         goto BufferOverflow;
739                     }
740                 }
741 
742                 State = ASL_NORMAL_CHAR;
743                 goto DoCharacter;
744                 break;
745             }
746 
747             /* Append another digit of the constant */
748 
749             ConvertBuffer[i] = StringChar;
750             i++;
751             continue;
752 
753         case ASL_HEX_CONSTANT:
754 
755             /* Up to two hex digits allowed */
756 
757             if (!isxdigit (StringChar) ||
758                 (i > 1))
759             {
760                 /*
761                  * Reached end of the constant. Convert the assembled ASCII
762                  * string and resume processing of the next character
763                  */
764                 ConvertBuffer[i] = 0;
765                 Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);
766 
767                 /* Check for NULL or non-ascii character (ignore if so) */
768 
769                 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
770                 {
771                     AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
772                         Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
773                         Gbl_CurrentLineOffset, Gbl_CurrentColumn,
774                         Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
775                 }
776                 else
777                 {
778                     *StringBuffer = (char) Digit;
779                     StringBuffer++;
780                     if (StringBuffer >= EndBuffer)
781                     {
782                         goto BufferOverflow;
783                     }
784                 }
785 
786                 State = ASL_NORMAL_CHAR;
787                 goto DoCharacter;
788                 break;
789             }
790 
791             /* Append another digit of the constant */
792 
793             ConvertBuffer[i] = StringChar;
794             i++;
795             continue;
796 
797         default:
798 
799             break;
800         }
801 
802         /* Save the finished character */
803 
804         *StringBuffer = StringChar;
805         StringBuffer++;
806         if (StringBuffer >= EndBuffer)
807         {
808             goto BufferOverflow;
809         }
810     }
811 
812     /*
813      * Premature End-Of-File
814      */
815     AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
816         Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
817         Gbl_CurrentLineOffset, Gbl_CurrentColumn,
818         Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
819     return (FALSE);
820 
821 
822 CompletedString:
823     /*
824      * Null terminate the input string and copy string to a new buffer
825      */
826     *StringBuffer = 0;
827 
828     CleanString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
829     if (!CleanString)
830     {
831         AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
832             Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
833             Gbl_CurrentLineOffset, Gbl_CurrentColumn,
834             Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
835         return (FALSE);
836     }
837 
838     strcpy (CleanString, MsgBuffer);
839     AslCompilerlval.s = CleanString;
840     return (TRUE);
841 
842 
843 BufferOverflow:
844 
845     /* Literal was too long */
846 
847     AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
848         Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
849         Gbl_CurrentLineOffset, Gbl_CurrentColumn,
850         Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
851     return (FALSE);
852 }
853