asremove.c revision 1.1.1.10 1 /******************************************************************************
2 *
3 * Module Name: asremove - Source conversion - removal functions
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2017, 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 MERCHANTIBILITY 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
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
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 SubBuffer = Buffer;
160 SubString = Buffer;
161
162 while (SubString)
163 {
164 SubBuffer = strstr (SubString, Keyword);
165 if (!SubBuffer)
166 {
167 return;
168 }
169
170 /*
171 * Check for translation escape string -- means to ignore
172 * blocks of code while replacing
173 */
174 if (Gbl_IgnoreTranslationEscapes)
175 {
176 Comment = NULL;
177 }
178 else
179 {
180 Comment = strstr (SubString, AS_START_IGNORE);
181 }
182
183 if ((Comment) &&
184 (Comment < SubBuffer))
185 {
186 SubString = strstr (Comment, AS_STOP_IGNORE);
187 if (!SubString)
188 {
189 return;
190 }
191
192 SubString += 3;
193 continue;
194 }
195
196 /* Check for ordinary comment */
197
198 Comment = strstr (SubString, "/*");
199
200 if ((Comment) &&
201 (Comment < SubBuffer))
202 {
203 SubString = strstr (Comment, "*/");
204 if (!SubString)
205 {
206 return;
207 }
208
209 SubString += 2;
210 continue;
211 }
212
213 SubString = SubBuffer;
214 if (!AsMatchExactWord (SubString, KeywordLength))
215 {
216 SubString++;
217 continue;
218 }
219
220 /* Find start of this line */
221
222 while (*SubString != '\n' && (SubString > Buffer))
223 {
224 SubString--;
225 }
226
227 SubString++;
228
229 /* Find the "#ifxxxx" */
230
231 IfPtr = strstr (SubString, "#if");
232 if (!IfPtr)
233 {
234 return;
235 }
236
237 if (IfPtr > SubBuffer)
238 {
239 /* Not the right #if */
240
241 SubString = SubBuffer + strlen (Keyword);
242 continue;
243 }
244
245 /* Find closing #endif or #else */
246
247 EndifPtr = strstr (SubBuffer, "#endif");
248 if (!EndifPtr)
249 {
250 /* There has to be an #endif */
251
252 return;
253 }
254
255 ElsePtr = strstr (SubBuffer, "#else");
256 if ((ElsePtr) &&
257 (EndifPtr > ElsePtr))
258 {
259 /* This #ifdef contains an #else clause */
260 /* Find end of this line */
261
262 SubBuffer = AsSkipPastChar (ElsePtr, '\n');
263 if (!SubBuffer)
264 {
265 return;
266 }
267
268 /* Remove the #ifdef .... #else code */
269
270 AsRemoveData (SubString, SubBuffer);
271
272 /* Next, we will remove the #endif statement */
273
274 EndifPtr = strstr (SubString, "#endif");
275 if (!EndifPtr)
276 {
277 /* There has to be an #endif */
278
279 return;
280 }
281
282 SubString = EndifPtr;
283 }
284
285 /* Remove the ... #endif part */
286 /* Find end of this line */
287
288 SubBuffer = AsSkipPastChar (EndifPtr, '\n');
289 if (!SubBuffer)
290 {
291 return;
292 }
293
294 /* Remove the lines */
295
296 SubBuffer = AsRemoveData (SubString, SubBuffer);
297 }
298 }
299
300
301 #ifdef _OBSOLETE_FUNCTIONS
302 /******************************************************************************
303 *
304 * FUNCTION: AsRemoveMacro
305 *
306 * DESCRIPTION: Remove every line that contains the keyword. Does not
307 * skip comments.
308 *
309 ******************************************************************************/
310
311 NOTE: This function is no longer used and is commented out for now.
312
313 Also, it appears to have one or more bugs in it. It can incorrectly remove
314 lines of code, producing some garbage.
315
316 void
317 AsRemoveMacro (
318 char *Buffer,
319 char *Keyword)
320 {
321 char *SubString;
322 char *SubBuffer;
323 int NestLevel;
324
325
326 SubBuffer = Buffer;
327 SubString = Buffer;
328
329 while (SubString)
330 {
331 SubString = strstr (SubBuffer, Keyword);
332
333 if (SubString)
334 {
335 SubBuffer = SubString;
336
337 /* Find start of the macro parameters */
338
339 while (*SubString != '(')
340 {
341 SubString++;
342 }
343 SubString++;
344
345 /* Remove the macro name and opening paren */
346
347 SubString = AsRemoveData (SubBuffer, SubString);
348
349 NestLevel = 1;
350 while (*SubString)
351 {
352 if (*SubString == '(')
353 {
354 NestLevel++;
355 }
356 else if (*SubString == ')')
357 {
358 NestLevel--;
359 }
360
361 SubString++;
362
363 if (NestLevel == 0)
364 {
365 break;
366 }
367 }
368
369 /* Remove the closing paren */
370
371 SubBuffer = AsRemoveData (SubString-1, SubString);
372 }
373 }
374 }
375 #endif
376
377 /******************************************************************************
378 *
379 * FUNCTION: AsRemoveLine
380 *
381 * DESCRIPTION: Remove every line that contains the keyword. Does not
382 * skip comments.
383 *
384 ******************************************************************************/
385
386 void
387 AsRemoveLine (
388 char *Buffer,
389 char *Keyword)
390 {
391 char *SubString;
392 char *SubBuffer;
393
394
395 SubBuffer = Buffer;
396 SubString = Buffer;
397
398 while (SubString)
399 {
400 SubString = strstr (SubBuffer, Keyword);
401
402 if (SubString)
403 {
404 SubBuffer = SubString;
405
406 /* Find start of this line */
407
408 while (*SubString != '\n')
409 {
410 SubString--;
411 }
412 SubString++;
413
414 /* Find end of this line */
415
416 SubBuffer = AsSkipPastChar (SubBuffer, '\n');
417 if (!SubBuffer)
418 {
419 return;
420 }
421
422 /* Remove the line */
423
424 SubBuffer = AsRemoveData (SubString, SubBuffer);
425 }
426 }
427 }
428
429
430 /******************************************************************************
431 *
432 * FUNCTION: AsReduceTypedefs
433 *
434 * DESCRIPTION: Eliminate certain typedefs
435 *
436 ******************************************************************************/
437
438 void
439 AsReduceTypedefs (
440 char *Buffer,
441 char *Keyword)
442 {
443 char *SubString;
444 char *SubBuffer;
445 char *SubSubString;
446 int NestLevel;
447
448
449 SubBuffer = Buffer;
450 SubString = Buffer;
451
452 while (SubString)
453 {
454 SubString = strstr (SubBuffer, Keyword);
455
456 if (SubString)
457 {
458 SubSubString = SubString + strlen (Keyword);
459
460 /* skip spaces */
461
462 while (strchr(" \t\r\n", *SubSubString))
463 {
464 SubSubString++;
465 }
466
467 /* skip type name */
468
469 while (!strchr(" \t\r\n", *SubSubString))
470 {
471 SubSubString++;
472 }
473
474 /* skip spaces */
475
476 while (strchr(" \t\r\n", *SubSubString))
477 {
478 SubSubString++;
479 }
480
481 if (*SubSubString == '{')
482 {
483 /* Remove the typedef itself */
484
485 SubBuffer = SubString + strlen ("typedef") + 1;
486 SubBuffer = AsRemoveData (SubString, SubBuffer);
487
488 /* Find the opening brace of the struct or union */
489
490 while (*SubString != '{')
491 {
492 SubString++;
493 }
494 SubString++;
495
496 /* Find the closing brace. Handles nested braces */
497
498 NestLevel = 1;
499 while (*SubString)
500 {
501 if (*SubString == '{')
502 {
503 NestLevel++;
504 }
505 else if (*SubString == '}')
506 {
507 NestLevel--;
508 }
509
510 SubString++;
511
512 if (NestLevel == 0)
513 {
514 break;
515 }
516 }
517
518 /* Remove an extra line feed if present */
519
520 if (!strncmp (SubString - 3, "\n\n", 2))
521 {
522 *(SubString -2) = '}';
523 SubString--;
524 }
525
526 /* Find the end of the typedef name */
527
528 SubBuffer = AsSkipUntilChar (SubString, ';');
529
530 /* And remove the typedef name */
531
532 SubBuffer = AsRemoveData (SubString, SubBuffer);
533 }
534 else
535 {
536 /* Skip the entire definition */
537
538 SubString = strchr (SubString, ';') + 1;
539 SubBuffer = SubString;
540 }
541 }
542 }
543 }
544
545
546 /******************************************************************************
547 *
548 * FUNCTION: AsRemoveEmptyBlocks
549 *
550 * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This
551 * can happen as a result of removing lines such as DEBUG_PRINT.
552 *
553 ******************************************************************************/
554
555 void
556 AsRemoveEmptyBlocks (
557 char *Buffer,
558 char *Filename)
559 {
560 char *SubBuffer;
561 char *BlockStart;
562 BOOLEAN EmptyBlock = TRUE;
563 BOOLEAN AnotherPassRequired = TRUE;
564 UINT32 BlockCount = 0;
565
566
567 while (AnotherPassRequired)
568 {
569 SubBuffer = Buffer;
570 AnotherPassRequired = FALSE;
571
572 while (*SubBuffer)
573 {
574 if (*SubBuffer == '{')
575 {
576 BlockStart = SubBuffer;
577 EmptyBlock = TRUE;
578
579 SubBuffer++;
580 while (*SubBuffer != '}')
581 {
582 if ((*SubBuffer != ' ') &&
583 (*SubBuffer != '\n'))
584 {
585 EmptyBlock = FALSE;
586 break;
587 }
588
589 SubBuffer++;
590 }
591
592 if (EmptyBlock)
593 {
594 /* Find start of the first line of the block */
595
596 while (*BlockStart != '\n')
597 {
598 BlockStart--;
599 }
600
601 /* Find end of the last line of the block */
602
603 SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
604 if (!SubBuffer)
605 {
606 break;
607 }
608
609 /* Remove the block */
610
611 SubBuffer = AsRemoveData (BlockStart, SubBuffer);
612 BlockCount++;
613 AnotherPassRequired = TRUE;
614 continue;
615 }
616 }
617
618 SubBuffer++;
619 }
620 }
621
622 if (BlockCount)
623 {
624 Gbl_MadeChanges = TRUE;
625 AsPrint ("Code blocks deleted", BlockCount, Filename);
626 }
627 }
628
629
630 /******************************************************************************
631 *
632 * FUNCTION: AsRemoveDebugMacros
633 *
634 * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output.
635 *
636 ******************************************************************************/
637
638 void
639 AsRemoveDebugMacros (
640 char *Buffer)
641 {
642 AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT");
643
644 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT", REPLACE_WHOLE_WORD);
645 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW", REPLACE_WHOLE_WORD);
646 AsRemoveStatement (Buffer, "DEBUG_EXEC", REPLACE_WHOLE_WORD);
647 AsRemoveStatement (Buffer, "FUNCTION_ENTRY", REPLACE_WHOLE_WORD);
648 AsRemoveStatement (Buffer, "PROC_NAME", REPLACE_WHOLE_WORD);
649 AsRemoveStatement (Buffer, "FUNCTION_TRACE", REPLACE_SUBSTRINGS);
650 AsRemoveStatement (Buffer, "DUMP_", REPLACE_SUBSTRINGS);
651
652 AsReplaceString ("return_VOID", "return", REPLACE_WHOLE_WORD, Buffer);
653 AsReplaceString ("return_PTR", "return", REPLACE_WHOLE_WORD, Buffer);
654 AsReplaceString ("return_STR", "return", REPLACE_WHOLE_WORD, Buffer);
655 AsReplaceString ("return_ACPI_STATUS", "return", REPLACE_WHOLE_WORD, Buffer);
656 AsReplaceString ("return_acpi_status", "return", REPLACE_WHOLE_WORD, Buffer);
657 AsReplaceString ("return_VALUE", "return", REPLACE_WHOLE_WORD, Buffer);
658 }
659
660
661 /******************************************************************************
662 *
663 * FUNCTION: AsCleanupSpecialMacro
664 *
665 * DESCRIPTION: For special macro invocations (invoked without ";" at the end
666 * of the lines), do the following:
667 * 1. Remove spaces appended by indent at the beginning of lines.
668 * 2. Add an empty line between two special macro invocations.
669 *
670 ******************************************************************************/
671
672 void
673 AsCleanupSpecialMacro (
674 char *Buffer,
675 char *Keyword)
676 {
677 char *SubString;
678 char *SubBuffer;
679 char *CommentEnd;
680 int NewLine;
681 int NestLevel;
682
683
684 SubBuffer = Buffer;
685 SubString = Buffer;
686
687 while (SubString)
688 {
689 SubString = strstr (SubBuffer, Keyword);
690
691 if (SubString)
692 {
693 /* Find start of the macro parameters */
694
695 while (*SubString != '(')
696 {
697 SubString++;
698 }
699
700 SubString++;
701
702 NestLevel = 1;
703 while (*SubString)
704 {
705 if (*SubString == '(')
706 {
707 NestLevel++;
708 }
709 else if (*SubString == ')')
710 {
711 NestLevel--;
712 }
713
714 SubString++;
715
716 if (NestLevel == 0)
717 {
718 break;
719 }
720 }
721
722 SkipLine:
723
724 /* Find end of the line */
725
726 NewLine = FALSE;
727 while (!NewLine && *SubString)
728 {
729 if (*SubString == '\n' && *(SubString - 1) != '\\')
730 {
731 NewLine = TRUE;
732 }
733
734 SubString++;
735 }
736
737 /* Find end of the line */
738
739 if (*SubString == '#' || *SubString == '\n')
740 {
741 goto SkipLine;
742 }
743
744 SubBuffer = SubString;
745
746 /* Find start of the non-space */
747
748 while (*SubString == ' ')
749 {
750 SubString++;
751 }
752
753 /* Find end of the line */
754
755 if (*SubString == '#' || *SubString == '\n')
756 {
757 goto SkipLine;
758 }
759
760 /* Find end of the line */
761
762 if (*SubString == '/' || *SubString == '*')
763 {
764 CommentEnd = strstr (SubString, "*/");
765 if (CommentEnd)
766 {
767 SubString = CommentEnd + 2;
768 goto SkipLine;
769 }
770 }
771
772 SubString = AsRemoveData (SubBuffer, SubString);
773 }
774 }
775 }
776