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