aslsupport.l revision 1.9 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 - 2017, 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 UtStringCacheCalloc (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 (Gbl_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 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 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 (Gbl_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 (Gbl_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 (Gbl_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 (Gbl_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 (Gbl_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 = UtStringCacheCalloc (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