asremove.c revision 1.1.1.3 1 /******************************************************************************
2 *
3 * Module Name: asremove - Source conversion - removal functions
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2013, 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 /******************************************************************************
303 *
304 * FUNCTION: AsRemoveMacro
305 *
306 * DESCRIPTION: Remove every line that contains the keyword. Does not
307 * skip comments.
308 *
309 ******************************************************************************/
310
311 void
312 AsRemoveMacro (
313 char *Buffer,
314 char *Keyword)
315 {
316 char *SubString;
317 char *SubBuffer;
318 int NestLevel;
319
320
321 SubBuffer = Buffer;
322 SubString = Buffer;
323
324
325 while (SubString)
326 {
327 SubString = strstr (SubBuffer, Keyword);
328
329 if (SubString)
330 {
331 SubBuffer = SubString;
332
333 /* Find start of the macro parameters */
334
335 while (*SubString != '(')
336 {
337 SubString++;
338 }
339 SubString++;
340
341 /* Remove the macro name and opening paren */
342
343 SubString = AsRemoveData (SubBuffer, SubString);
344
345 NestLevel = 1;
346 while (*SubString)
347 {
348 if (*SubString == '(')
349 {
350 NestLevel++;
351 }
352 else if (*SubString == ')')
353 {
354 NestLevel--;
355 }
356
357 SubString++;
358
359 if (NestLevel == 0)
360 {
361 break;
362 }
363 }
364
365 /* Remove the closing paren */
366
367 SubBuffer = AsRemoveData (SubString-1, SubString);
368 }
369 }
370 }
371
372
373 /******************************************************************************
374 *
375 * FUNCTION: AsRemoveLine
376 *
377 * DESCRIPTION: Remove every line that contains the keyword. Does not
378 * skip comments.
379 *
380 ******************************************************************************/
381
382 void
383 AsRemoveLine (
384 char *Buffer,
385 char *Keyword)
386 {
387 char *SubString;
388 char *SubBuffer;
389
390
391 SubBuffer = Buffer;
392 SubString = Buffer;
393
394
395 while (SubString)
396 {
397 SubString = strstr (SubBuffer, Keyword);
398
399 if (SubString)
400 {
401 SubBuffer = SubString;
402
403 /* Find start of this line */
404
405 while (*SubString != '\n')
406 {
407 SubString--;
408 }
409 SubString++;
410
411 /* Find end of this line */
412
413 SubBuffer = AsSkipPastChar (SubBuffer, '\n');
414 if (!SubBuffer)
415 {
416 return;
417 }
418
419 /* Remove the line */
420
421 SubBuffer = AsRemoveData (SubString, SubBuffer);
422 }
423 }
424 }
425
426
427 /******************************************************************************
428 *
429 * FUNCTION: AsReduceTypedefs
430 *
431 * DESCRIPTION: Eliminate certain typedefs
432 *
433 ******************************************************************************/
434
435 void
436 AsReduceTypedefs (
437 char *Buffer,
438 char *Keyword)
439 {
440 char *SubString;
441 char *SubBuffer;
442 int NestLevel;
443
444
445 SubBuffer = Buffer;
446 SubString = Buffer;
447
448
449 while (SubString)
450 {
451 SubString = strstr (SubBuffer, Keyword);
452
453 if (SubString)
454 {
455 /* Remove the typedef itself */
456
457 SubBuffer = SubString + strlen ("typedef") + 1;
458 SubBuffer = AsRemoveData (SubString, SubBuffer);
459
460 /* Find the opening brace of the struct or union */
461
462 while (*SubString != '{')
463 {
464 SubString++;
465 }
466 SubString++;
467
468 /* Find the closing brace. Handles nested braces */
469
470 NestLevel = 1;
471 while (*SubString)
472 {
473 if (*SubString == '{')
474 {
475 NestLevel++;
476 }
477 else if (*SubString == '}')
478 {
479 NestLevel--;
480 }
481
482 SubString++;
483
484 if (NestLevel == 0)
485 {
486 break;
487 }
488 }
489
490 /* Remove an extra line feed if present */
491
492 if (!strncmp (SubString - 3, "\n\n", 2))
493 {
494 *(SubString -2) = '}';
495 SubString--;
496 }
497
498 /* Find the end of the typedef name */
499
500 SubBuffer = AsSkipUntilChar (SubString, ';');
501
502 /* And remove the typedef name */
503
504 SubBuffer = AsRemoveData (SubString, SubBuffer);
505 }
506 }
507 }
508
509
510 /******************************************************************************
511 *
512 * FUNCTION: AsRemoveEmptyBlocks
513 *
514 * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This
515 * can happen as a result of removing lines such as DEBUG_PRINT.
516 *
517 ******************************************************************************/
518
519 void
520 AsRemoveEmptyBlocks (
521 char *Buffer,
522 char *Filename)
523 {
524 char *SubBuffer;
525 char *BlockStart;
526 BOOLEAN EmptyBlock = TRUE;
527 BOOLEAN AnotherPassRequired = TRUE;
528 UINT32 BlockCount = 0;
529
530
531 while (AnotherPassRequired)
532 {
533 SubBuffer = Buffer;
534 AnotherPassRequired = FALSE;
535
536 while (*SubBuffer)
537 {
538 if (*SubBuffer == '{')
539 {
540 BlockStart = SubBuffer;
541 EmptyBlock = TRUE;
542
543 SubBuffer++;
544 while (*SubBuffer != '}')
545 {
546 if ((*SubBuffer != ' ') &&
547 (*SubBuffer != '\n'))
548 {
549 EmptyBlock = FALSE;
550 break;
551 }
552 SubBuffer++;
553 }
554
555 if (EmptyBlock)
556 {
557 /* Find start of the first line of the block */
558
559 while (*BlockStart != '\n')
560 {
561 BlockStart--;
562 }
563
564 /* Find end of the last line of the block */
565
566 SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
567 if (!SubBuffer)
568 {
569 break;
570 }
571
572 /* Remove the block */
573
574 SubBuffer = AsRemoveData (BlockStart, SubBuffer);
575 BlockCount++;
576 AnotherPassRequired = TRUE;
577 continue;
578 }
579 }
580
581 SubBuffer++;
582 }
583 }
584
585 if (BlockCount)
586 {
587 Gbl_MadeChanges = TRUE;
588 AsPrint ("Code blocks deleted", BlockCount, Filename);
589 }
590 }
591
592
593 /******************************************************************************
594 *
595 * FUNCTION: AsRemoveDebugMacros
596 *
597 * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output.
598 *
599 ******************************************************************************/
600
601 void
602 AsRemoveDebugMacros (
603 char *Buffer)
604 {
605 AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT");
606
607 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT", REPLACE_WHOLE_WORD);
608 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW", REPLACE_WHOLE_WORD);
609 AsRemoveStatement (Buffer, "DEBUG_EXEC", REPLACE_WHOLE_WORD);
610 AsRemoveStatement (Buffer, "FUNCTION_ENTRY", REPLACE_WHOLE_WORD);
611 AsRemoveStatement (Buffer, "PROC_NAME", REPLACE_WHOLE_WORD);
612 AsRemoveStatement (Buffer, "FUNCTION_TRACE", REPLACE_SUBSTRINGS);
613 AsRemoveStatement (Buffer, "DUMP_", REPLACE_SUBSTRINGS);
614
615 AsReplaceString ("return_VOID", "return", REPLACE_WHOLE_WORD, Buffer);
616 AsReplaceString ("return_PTR", "return", REPLACE_WHOLE_WORD, Buffer);
617 AsReplaceString ("return_ACPI_STATUS", "return", REPLACE_WHOLE_WORD, Buffer);
618 AsReplaceString ("return_acpi_status", "return", REPLACE_WHOLE_WORD, Buffer);
619 AsReplaceString ("return_VALUE", "return", REPLACE_WHOLE_WORD, Buffer);
620 }
621
622
623 /******************************************************************************
624 *
625 * FUNCTION: AsCleanupSpecialMacro
626 *
627 * DESCRIPTION: For special macro invocations (invoked without ";" at the end
628 * of the lines), do the following:
629 * 1. Remove spaces appended by indent at the beginning of lines.
630 * 2. Add an empty line between two special macro invocations.
631 *
632 ******************************************************************************/
633
634 void
635 AsCleanupSpecialMacro (
636 char *Buffer,
637 char *Keyword)
638 {
639 char *SubString;
640 char *SubBuffer;
641 char *CommentEnd;
642 int NewLine;
643 int NestLevel;
644
645
646 SubBuffer = Buffer;
647 SubString = Buffer;
648
649 while (SubString)
650 {
651 SubString = strstr (SubBuffer, Keyword);
652
653 if (SubString)
654 {
655 /* Find start of the macro parameters */
656
657 while (*SubString != '(')
658 {
659 SubString++;
660 }
661 SubString++;
662
663 NestLevel = 1;
664 while (*SubString)
665 {
666 if (*SubString == '(')
667 {
668 NestLevel++;
669 }
670 else if (*SubString == ')')
671 {
672 NestLevel--;
673 }
674
675 SubString++;
676
677 if (NestLevel == 0)
678 {
679 break;
680 }
681 }
682
683 SkipLine:
684
685 /* Find end of the line */
686
687 NewLine = FALSE;
688 while (!NewLine && *SubString)
689 {
690 if (*SubString == '\n' && *(SubString - 1) != '\\')
691 {
692 NewLine = TRUE;
693 }
694 SubString++;
695 }
696
697 /* Find end of the line */
698
699 if (*SubString == '#' || *SubString == '\n')
700 {
701 goto SkipLine;
702 }
703
704 SubBuffer = SubString;
705
706 /* Find start of the non-space */
707
708 while (*SubString == ' ')
709 {
710 SubString++;
711 }
712
713 /* Find end of the line */
714
715 if (*SubString == '#' || *SubString == '\n')
716 {
717 goto SkipLine;
718 }
719
720 /* Find end of the line */
721
722 if (*SubString == '/' || *SubString == '*')
723 {
724 CommentEnd = strstr (SubString, "*/");
725 if (CommentEnd)
726 {
727 SubString = CommentEnd + 2;
728 goto SkipLine;
729 }
730 }
731
732 SubString = AsRemoveData (SubBuffer, SubString);
733 }
734 }
735 }
736