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