1 /******************************************************************************
2 *
3 * Module Name: asremove - Source conversion - removal functions
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpisrc.h"
45
46 /* Local prototypes */
47
48 void
49 AsRemoveStatement (
50 char *Buffer,
51 char *Keyword,
52 UINT32 Type);
53
54
55 /******************************************************************************
56 *
57 * FUNCTION: AsRemoveStatement
58 *
59 * DESCRIPTION: Remove all statements that contain the given keyword.
60 * Limitations: Removes text from the start of the line that
61 * contains the keyword to the next semicolon. Currently
62 * doesn't ignore comments.
63 *
64 ******************************************************************************/
65
66 void
AsRemoveStatement(char * Buffer,char * Keyword,UINT32 Type)67 AsRemoveStatement (
68 char *Buffer,
69 char *Keyword,
70 UINT32 Type)
71 {
72 char *SubString;
73 char *SubBuffer;
74 int KeywordLength;
75
76
77 KeywordLength = strlen (Keyword);
78 SubBuffer = Buffer;
79 SubString = Buffer;
80
81 while (SubString)
82 {
83 SubString = strstr (SubBuffer, Keyword);
84
85 if (SubString)
86 {
87 SubBuffer = SubString;
88
89 if ((Type == REPLACE_WHOLE_WORD) &&
90 (!AsMatchExactWord (SubString, KeywordLength)))
91 {
92 SubBuffer++;
93 continue;
94 }
95
96 /* Find start of this line */
97
98 while (*SubString != '\n')
99 {
100 SubString--;
101 }
102 SubString++;
103
104 /* Find end of this statement */
105
106 SubBuffer = AsSkipPastChar (SubBuffer, ';');
107 if (!SubBuffer)
108 {
109 return;
110 }
111
112 /* Find end of this line */
113
114 SubBuffer = AsSkipPastChar (SubBuffer, '\n');
115 if (!SubBuffer)
116 {
117 return;
118 }
119
120 /* If next line is blank, remove it too */
121
122 if (*SubBuffer == '\n')
123 {
124 SubBuffer++;
125 }
126
127 /* Remove the lines */
128
129 SubBuffer = AsRemoveData (SubString, SubBuffer);
130 }
131 }
132 }
133
134
135 /******************************************************************************
136 *
137 * FUNCTION: AsRemoveConditionalCompile
138 *
139 * DESCRIPTION: Remove a "#ifdef" statement, and all text that it encompasses.
140 * Limitations: cannot handle nested ifdefs.
141 *
142 ******************************************************************************/
143
144 void
AsRemoveConditionalCompile(char * Buffer,char * Keyword)145 AsRemoveConditionalCompile (
146 char *Buffer,
147 char *Keyword)
148 {
149 char *SubString;
150 char *SubBuffer;
151 char *IfPtr;
152 char *EndifPtr;
153 char *ElsePtr;
154 char *Comment;
155 int KeywordLength;
156
157
158 KeywordLength = strlen (Keyword);
159 SubString = Buffer;
160
161 while (SubString)
162 {
163 SubBuffer = strstr (SubString, Keyword);
164 if (!SubBuffer)
165 {
166 return;
167 }
168
169 /*
170 * Check for translation escape string -- means to ignore
171 * blocks of code while replacing
172 */
173 if (Gbl_IgnoreTranslationEscapes)
174 {
175 Comment = NULL;
176 }
177 else
178 {
179 Comment = strstr (SubString, AS_START_IGNORE);
180 }
181
182 if ((Comment) &&
183 (Comment < SubBuffer))
184 {
185 SubString = strstr (Comment, AS_STOP_IGNORE);
186 if (!SubString)
187 {
188 return;
189 }
190
191 SubString += 3;
192 continue;
193 }
194
195 /* Check for ordinary comment */
196
197 Comment = strstr (SubString, "/*");
198
199 if ((Comment) &&
200 (Comment < SubBuffer))
201 {
202 SubString = strstr (Comment, "*/");
203 if (!SubString)
204 {
205 return;
206 }
207
208 SubString += 2;
209 continue;
210 }
211
212 SubString = SubBuffer;
213 if (!AsMatchExactWord (SubString, KeywordLength))
214 {
215 SubString++;
216 continue;
217 }
218
219 /* Find start of this line */
220
221 while (*SubString != '\n' && (SubString > Buffer))
222 {
223 SubString--;
224 }
225
226 SubString++;
227
228 /* Find the "#ifxxxx" */
229
230 IfPtr = strstr (SubString, "#if");
231 if (!IfPtr)
232 {
233 return;
234 }
235
236 if (IfPtr > SubBuffer)
237 {
238 /* Not the right #if */
239
240 SubString = SubBuffer + strlen (Keyword);
241 continue;
242 }
243
244 /* Find closing #endif or #else */
245
246 EndifPtr = strstr (SubBuffer, "#endif");
247 if (!EndifPtr)
248 {
249 /* There has to be an #endif */
250
251 return;
252 }
253
254 ElsePtr = strstr (SubBuffer, "#else");
255 if ((ElsePtr) &&
256 (EndifPtr > ElsePtr))
257 {
258 /* This #ifdef contains an #else clause */
259 /* Find end of this line */
260
261 SubBuffer = AsSkipPastChar (ElsePtr, '\n');
262 if (!SubBuffer)
263 {
264 return;
265 }
266
267 /* Remove the #ifdef .... #else code */
268
269 AsRemoveData (SubString, SubBuffer);
270
271 /* Next, we will remove the #endif statement */
272
273 EndifPtr = strstr (SubString, "#endif");
274 if (!EndifPtr)
275 {
276 /* There has to be an #endif */
277
278 return;
279 }
280
281 SubString = EndifPtr;
282 }
283
284 /* Remove the ... #endif part */
285 /* Find end of this line */
286
287 SubBuffer = AsSkipPastChar (EndifPtr, '\n');
288 if (!SubBuffer)
289 {
290 return;
291 }
292
293 /* Remove the lines */
294
295 (void) AsRemoveData (SubString, SubBuffer);
296 }
297 }
298
299
300 #ifdef _OBSOLETE_FUNCTIONS
301 /******************************************************************************
302 *
303 * FUNCTION: AsRemoveMacro
304 *
305 * DESCRIPTION: Remove every line that contains the keyword. Does not
306 * skip comments.
307 *
308 ******************************************************************************/
309
310 NOTE: This function is no longer used and is commented out for now.
311
312 Also, it appears to have one or more bugs in it. It can incorrectly remove
313 lines of code, producing some garbage.
314
315 void
316 AsRemoveMacro (
317 char *Buffer,
318 char *Keyword)
319 {
320 char *SubString;
321 char *SubBuffer;
322 int NestLevel;
323
324
325 SubBuffer = Buffer;
326 SubString = Buffer;
327
328 while (SubString)
329 {
330 SubString = strstr (SubBuffer, Keyword);
331
332 if (SubString)
333 {
334 SubBuffer = SubString;
335
336 /* Find start of the macro parameters */
337
338 while (*SubString != '(')
339 {
340 SubString++;
341 }
342 SubString++;
343
344 /* Remove the macro name and opening paren */
345
346 SubString = AsRemoveData (SubBuffer, SubString);
347
348 NestLevel = 1;
349 while (*SubString)
350 {
351 if (*SubString == '(')
352 {
353 NestLevel++;
354 }
355 else if (*SubString == ')')
356 {
357 NestLevel--;
358 }
359
360 SubString++;
361
362 if (NestLevel == 0)
363 {
364 break;
365 }
366 }
367
368 /* Remove the closing paren */
369
370 SubBuffer = AsRemoveData (SubString-1, SubString);
371 }
372 }
373 }
374 #endif
375
376 /******************************************************************************
377 *
378 * FUNCTION: AsRemoveLine
379 *
380 * DESCRIPTION: Remove every line that contains the keyword. Does not
381 * skip comments.
382 *
383 ******************************************************************************/
384
385 void
AsRemoveLine(char * Buffer,char * Keyword)386 AsRemoveLine (
387 char *Buffer,
388 char *Keyword)
389 {
390 char *SubString;
391 char *SubBuffer;
392
393
394 SubBuffer = Buffer;
395 SubString = Buffer;
396
397 while (SubString)
398 {
399 SubString = strstr (SubBuffer, Keyword);
400
401 if (SubString)
402 {
403 SubBuffer = SubString;
404
405 /* Find start of this line */
406
407 while (*SubString != '\n')
408 {
409 SubString--;
410 }
411 SubString++;
412
413 /* Find end of this line */
414
415 SubBuffer = AsSkipPastChar (SubBuffer, '\n');
416 if (!SubBuffer)
417 {
418 return;
419 }
420
421 /* Remove the line */
422
423 SubBuffer = AsRemoveData (SubString, SubBuffer);
424 }
425 }
426 }
427
428
429 /******************************************************************************
430 *
431 * FUNCTION: AsReduceTypedefs
432 *
433 * DESCRIPTION: Eliminate certain typedefs
434 *
435 ******************************************************************************/
436
437 void
AsReduceTypedefs(char * Buffer,char * Keyword)438 AsReduceTypedefs (
439 char *Buffer,
440 char *Keyword)
441 {
442 char *SubString;
443 char *SubBuffer;
444 char *SubSubString;
445 int NestLevel;
446
447
448 SubBuffer = Buffer;
449 SubString = Buffer;
450
451 while (SubString)
452 {
453 SubString = strstr (SubBuffer, Keyword);
454
455 if (SubString)
456 {
457 SubSubString = SubString + strlen (Keyword);
458
459 /* skip spaces */
460
461 while (strchr(" \t\r\n", *SubSubString))
462 {
463 SubSubString++;
464 }
465
466 /* skip type name */
467
468 while (!strchr(" \t\r\n", *SubSubString))
469 {
470 SubSubString++;
471 }
472
473 /* skip spaces */
474
475 while (strchr(" \t\r\n", *SubSubString))
476 {
477 SubSubString++;
478 }
479
480 if (*SubSubString == '{')
481 {
482 /* Remove the typedef itself */
483
484 SubBuffer = SubString + strlen ("typedef") + 1;
485 (void) AsRemoveData (SubString, SubBuffer);
486
487 /* Find the opening brace of the struct or union */
488
489 while (*SubString != '{')
490 {
491 SubString++;
492 }
493 SubString++;
494
495 /* Find the closing brace. Handles nested braces */
496
497 NestLevel = 1;
498 while (*SubString)
499 {
500 if (*SubString == '{')
501 {
502 NestLevel++;
503 }
504 else if (*SubString == '}')
505 {
506 NestLevel--;
507 }
508
509 SubString++;
510
511 if (NestLevel == 0)
512 {
513 break;
514 }
515 }
516
517 /* Remove an extra line feed if present */
518
519 if (!strncmp (SubString - 3, "\n\n", 2))
520 {
521 *(SubString -2) = '}';
522 SubString--;
523 }
524
525 /* Find the end of the typedef name */
526
527 SubBuffer = AsSkipUntilChar (SubString, ';');
528
529 /* And remove the typedef name */
530
531 SubBuffer = AsRemoveData (SubString, SubBuffer);
532 }
533 else
534 {
535 /* Skip the entire definition */
536
537 SubString = strchr (SubString, ';') + 1;
538 SubBuffer = SubString;
539 }
540 }
541 }
542 }
543
544
545 /******************************************************************************
546 *
547 * FUNCTION: AsRemoveEmptyBlocks
548 *
549 * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This
550 * can happen as a result of removing lines such as DEBUG_PRINT.
551 *
552 ******************************************************************************/
553
554 void
AsRemoveEmptyBlocks(char * Buffer,char * Filename)555 AsRemoveEmptyBlocks (
556 char *Buffer,
557 char *Filename)
558 {
559 char *SubBuffer;
560 char *BlockStart;
561 BOOLEAN EmptyBlock = TRUE;
562 BOOLEAN AnotherPassRequired = TRUE;
563 UINT32 BlockCount = 0;
564
565
566 while (AnotherPassRequired)
567 {
568 SubBuffer = Buffer;
569 AnotherPassRequired = FALSE;
570
571 while (*SubBuffer)
572 {
573 if (*SubBuffer == '{')
574 {
575 BlockStart = SubBuffer;
576 EmptyBlock = TRUE;
577
578 SubBuffer++;
579 while (*SubBuffer != '}')
580 {
581 if ((*SubBuffer != ' ') &&
582 (*SubBuffer != '\n'))
583 {
584 EmptyBlock = FALSE;
585 break;
586 }
587
588 SubBuffer++;
589 }
590
591 if (EmptyBlock)
592 {
593 /* Find start of the first line of the block */
594
595 while (*BlockStart != '\n')
596 {
597 BlockStart--;
598 }
599
600 /* Find end of the last line of the block */
601
602 SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
603 if (!SubBuffer)
604 {
605 break;
606 }
607
608 /* Remove the block */
609
610 SubBuffer = AsRemoveData (BlockStart, SubBuffer);
611 BlockCount++;
612 AnotherPassRequired = TRUE;
613 continue;
614 }
615 }
616
617 SubBuffer++;
618 }
619 }
620
621 if (BlockCount)
622 {
623 Gbl_MadeChanges = TRUE;
624 AsPrint ("Code blocks deleted", BlockCount, Filename);
625 }
626 }
627
628
629 /******************************************************************************
630 *
631 * FUNCTION: AsRemoveDebugMacros
632 *
633 * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output.
634 *
635 ******************************************************************************/
636
637 void
AsRemoveDebugMacros(char * Buffer)638 AsRemoveDebugMacros (
639 char *Buffer)
640 {
641 AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT");
642
643 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT", REPLACE_WHOLE_WORD);
644 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW", REPLACE_WHOLE_WORD);
645 AsRemoveStatement (Buffer, "DEBUG_EXEC", REPLACE_WHOLE_WORD);
646 AsRemoveStatement (Buffer, "FUNCTION_ENTRY", REPLACE_WHOLE_WORD);
647 AsRemoveStatement (Buffer, "PROC_NAME", REPLACE_WHOLE_WORD);
648 AsRemoveStatement (Buffer, "FUNCTION_TRACE", REPLACE_SUBSTRINGS);
649 AsRemoveStatement (Buffer, "DUMP_", REPLACE_SUBSTRINGS);
650
651 AsReplaceString ("return_VOID", "return", REPLACE_WHOLE_WORD, Buffer);
652 AsReplaceString ("return_PTR", "return", REPLACE_WHOLE_WORD, Buffer);
653 AsReplaceString ("return_STR", "return", REPLACE_WHOLE_WORD, Buffer);
654 AsReplaceString ("return_ACPI_STATUS", "return", REPLACE_WHOLE_WORD, Buffer);
655 AsReplaceString ("return_acpi_status", "return", REPLACE_WHOLE_WORD, Buffer);
656 AsReplaceString ("return_VALUE", "return", REPLACE_WHOLE_WORD, Buffer);
657 }
658
659
660 /******************************************************************************
661 *
662 * FUNCTION: AsCleanupSpecialMacro
663 *
664 * DESCRIPTION: For special macro invocations (invoked without ";" at the end
665 * of the lines), do the following:
666 * 1. Remove spaces appended by indent at the beginning of lines.
667 * 2. Add an empty line between two special macro invocations.
668 *
669 ******************************************************************************/
670
671 void
AsCleanupSpecialMacro(char * Buffer,char * Keyword)672 AsCleanupSpecialMacro (
673 char *Buffer,
674 char *Keyword)
675 {
676 char *SubString;
677 char *SubBuffer;
678 char *CommentEnd;
679 int NewLine;
680 int NestLevel;
681
682
683 SubBuffer = Buffer;
684 SubString = Buffer;
685
686 while (SubString)
687 {
688 SubString = strstr (SubBuffer, Keyword);
689
690 if (SubString)
691 {
692 /* Find start of the macro parameters */
693
694 while (*SubString != '(')
695 {
696 SubString++;
697 }
698
699 SubString++;
700
701 NestLevel = 1;
702 while (*SubString)
703 {
704 if (*SubString == '(')
705 {
706 NestLevel++;
707 }
708 else if (*SubString == ')')
709 {
710 NestLevel--;
711 }
712
713 SubString++;
714
715 if (NestLevel == 0)
716 {
717 break;
718 }
719 }
720
721 SkipLine:
722
723 /* Find end of the line */
724
725 NewLine = FALSE;
726 while (!NewLine && *SubString)
727 {
728 if (*SubString == '\n' && *(SubString - 1) != '\\')
729 {
730 NewLine = TRUE;
731 }
732
733 SubString++;
734 }
735
736 /* Find end of the line */
737
738 if (*SubString == '#' || *SubString == '\n')
739 {
740 goto SkipLine;
741 }
742
743 SubBuffer = SubString;
744
745 /* Find start of the non-space */
746
747 while (*SubString == ' ')
748 {
749 SubString++;
750 }
751
752 /* Find end of the line */
753
754 if (*SubString == '#' || *SubString == '\n')
755 {
756 goto SkipLine;
757 }
758
759 /* Find end of the line */
760
761 if (*SubString == '/' || *SubString == '*')
762 {
763 CommentEnd = strstr (SubString, "*/");
764 if (CommentEnd)
765 {
766 SubString = CommentEnd + 2;
767 goto SkipLine;
768 }
769 }
770
771 SubString = AsRemoveData (SubBuffer, SubString);
772 }
773 }
774 }
775