nrelease - fix/improve livecd
[dragonfly.git] / sys / contrib / dev / acpica / source / tools / acpisrc / asremove.c
1 /******************************************************************************
2  *
3  * Module Name: asremove - Source conversion - removal functions
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151
152 #include "acpisrc.h"
153
154 /* Local prototypes */
155
156 void
157 AsRemoveStatement (
158     char                    *Buffer,
159     char                    *Keyword,
160     UINT32                  Type);
161
162
163 /******************************************************************************
164  *
165  * FUNCTION:    AsRemoveStatement
166  *
167  * DESCRIPTION: Remove all statements that contain the given keyword.
168  *              Limitations:  Removes text from the start of the line that
169  *              contains the keyword to the next semicolon. Currently
170  *              doesn't ignore comments.
171  *
172  ******************************************************************************/
173
174 void
175 AsRemoveStatement (
176     char                    *Buffer,
177     char                    *Keyword,
178     UINT32                  Type)
179 {
180     char                    *SubString;
181     char                    *SubBuffer;
182     int                     KeywordLength;
183
184
185     KeywordLength = strlen (Keyword);
186     SubBuffer = Buffer;
187     SubString = Buffer;
188
189     while (SubString)
190     {
191         SubString = strstr (SubBuffer, Keyword);
192
193         if (SubString)
194         {
195             SubBuffer = SubString;
196
197             if ((Type == REPLACE_WHOLE_WORD) &&
198                 (!AsMatchExactWord (SubString, KeywordLength)))
199             {
200                 SubBuffer++;
201                 continue;
202             }
203
204             /* Find start of this line */
205
206             while (*SubString != '\n')
207             {
208                 SubString--;
209             }
210             SubString++;
211
212             /* Find end of this statement */
213
214             SubBuffer = AsSkipPastChar (SubBuffer, ';');
215             if (!SubBuffer)
216             {
217                 return;
218             }
219
220             /* Find end of this line */
221
222             SubBuffer = AsSkipPastChar (SubBuffer, '\n');
223             if (!SubBuffer)
224             {
225                 return;
226             }
227
228             /* If next line is blank, remove it too */
229
230             if (*SubBuffer == '\n')
231             {
232                 SubBuffer++;
233             }
234
235             /* Remove the lines */
236
237             SubBuffer = AsRemoveData (SubString, SubBuffer);
238         }
239     }
240 }
241
242
243 /******************************************************************************
244  *
245  * FUNCTION:    AsRemoveConditionalCompile
246  *
247  * DESCRIPTION: Remove a "#ifdef" statement, and all text that it encompasses.
248  *              Limitations: cannot handle nested ifdefs.
249  *
250  ******************************************************************************/
251
252 void
253 AsRemoveConditionalCompile (
254     char                    *Buffer,
255     char                    *Keyword)
256 {
257     char                    *SubString;
258     char                    *SubBuffer;
259     char                    *IfPtr;
260     char                    *EndifPtr;
261     char                    *ElsePtr;
262     char                    *Comment;
263     int                     KeywordLength;
264
265
266     KeywordLength = strlen (Keyword);
267     SubString = Buffer;
268
269     while (SubString)
270     {
271         SubBuffer = strstr (SubString, Keyword);
272         if (!SubBuffer)
273         {
274             return;
275         }
276
277         /*
278          * Check for translation escape string -- means to ignore
279          * blocks of code while replacing
280          */
281         if (Gbl_IgnoreTranslationEscapes)
282         {
283             Comment = NULL;
284         }
285         else
286         {
287             Comment = strstr (SubString, AS_START_IGNORE);
288         }
289
290         if ((Comment) &&
291             (Comment < SubBuffer))
292         {
293             SubString = strstr (Comment, AS_STOP_IGNORE);
294             if (!SubString)
295             {
296                 return;
297             }
298
299             SubString += 3;
300             continue;
301         }
302
303         /* Check for ordinary comment */
304
305         Comment = strstr (SubString, "/*");
306
307         if ((Comment) &&
308             (Comment < SubBuffer))
309         {
310             SubString = strstr (Comment, "*/");
311             if (!SubString)
312             {
313                 return;
314             }
315
316             SubString += 2;
317             continue;
318         }
319
320         SubString = SubBuffer;
321         if (!AsMatchExactWord (SubString, KeywordLength))
322         {
323             SubString++;
324             continue;
325         }
326
327         /* Find start of this line */
328
329         while (*SubString != '\n' && (SubString > Buffer))
330         {
331             SubString--;
332         }
333
334         SubString++;
335
336         /* Find the "#ifxxxx" */
337
338         IfPtr = strstr (SubString, "#if");
339         if (!IfPtr)
340         {
341             return;
342         }
343
344         if (IfPtr > SubBuffer)
345         {
346             /* Not the right #if */
347
348             SubString = SubBuffer + strlen (Keyword);
349             continue;
350         }
351
352         /* Find closing #endif or #else */
353
354         EndifPtr = strstr (SubBuffer, "#endif");
355         if (!EndifPtr)
356         {
357             /* There has to be an #endif */
358
359             return;
360         }
361
362         ElsePtr = strstr (SubBuffer, "#else");
363         if ((ElsePtr) &&
364             (EndifPtr > ElsePtr))
365         {
366             /* This #ifdef contains an #else clause */
367             /* Find end of this line */
368
369             SubBuffer = AsSkipPastChar (ElsePtr, '\n');
370             if (!SubBuffer)
371             {
372                 return;
373             }
374
375             /* Remove the #ifdef .... #else code */
376
377             AsRemoveData (SubString, SubBuffer);
378
379             /* Next, we will remove the #endif statement */
380
381             EndifPtr = strstr (SubString, "#endif");
382             if (!EndifPtr)
383             {
384                 /* There has to be an #endif */
385
386                 return;
387             }
388
389             SubString = EndifPtr;
390         }
391
392         /* Remove the ... #endif part */
393         /* Find end of this line */
394
395         SubBuffer = AsSkipPastChar (EndifPtr, '\n');
396         if (!SubBuffer)
397         {
398             return;
399         }
400
401         /* Remove the lines */
402
403         (void) AsRemoveData (SubString, SubBuffer);
404     }
405 }
406
407
408 #ifdef _OBSOLETE_FUNCTIONS
409 /******************************************************************************
410  *
411  * FUNCTION:    AsRemoveMacro
412  *
413  * DESCRIPTION: Remove every line that contains the keyword. Does not
414  *              skip comments.
415  *
416  ******************************************************************************/
417
418 NOTE: This function is no longer used and is commented out for now.
419
420 Also, it appears to have one or more bugs in it. It can incorrectly remove
421 lines of code, producing some garbage.
422
423 void
424 AsRemoveMacro (
425     char                    *Buffer,
426     char                    *Keyword)
427 {
428     char                    *SubString;
429     char                    *SubBuffer;
430     int                     NestLevel;
431
432
433     SubBuffer = Buffer;
434     SubString = Buffer;
435
436     while (SubString)
437     {
438         SubString = strstr (SubBuffer, Keyword);
439
440         if (SubString)
441         {
442             SubBuffer = SubString;
443
444             /* Find start of the macro parameters */
445
446             while (*SubString != '(')
447             {
448                 SubString++;
449             }
450             SubString++;
451
452             /* Remove the macro name and opening paren */
453
454             SubString = AsRemoveData (SubBuffer, SubString);
455
456             NestLevel = 1;
457             while (*SubString)
458             {
459                 if (*SubString == '(')
460                 {
461                     NestLevel++;
462                 }
463                 else if (*SubString == ')')
464                 {
465                     NestLevel--;
466                 }
467
468                 SubString++;
469
470                 if (NestLevel == 0)
471                 {
472                     break;
473                 }
474             }
475
476             /* Remove the closing paren */
477
478             SubBuffer = AsRemoveData (SubString-1, SubString);
479         }
480     }
481 }
482 #endif
483
484 /******************************************************************************
485  *
486  * FUNCTION:    AsRemoveLine
487  *
488  * DESCRIPTION: Remove every line that contains the keyword. Does not
489  *              skip comments.
490  *
491  ******************************************************************************/
492
493 void
494 AsRemoveLine (
495     char                    *Buffer,
496     char                    *Keyword)
497 {
498     char                    *SubString;
499     char                    *SubBuffer;
500
501
502     SubBuffer = Buffer;
503     SubString = Buffer;
504
505     while (SubString)
506     {
507         SubString = strstr (SubBuffer, Keyword);
508
509         if (SubString)
510         {
511             SubBuffer = SubString;
512
513             /* Find start of this line */
514
515             while (*SubString != '\n')
516             {
517                 SubString--;
518             }
519             SubString++;
520
521             /* Find end of this line */
522
523             SubBuffer = AsSkipPastChar (SubBuffer, '\n');
524             if (!SubBuffer)
525             {
526                 return;
527             }
528
529             /* Remove the line */
530
531             SubBuffer = AsRemoveData (SubString, SubBuffer);
532         }
533     }
534 }
535
536
537 /******************************************************************************
538  *
539  * FUNCTION:    AsReduceTypedefs
540  *
541  * DESCRIPTION: Eliminate certain typedefs
542  *
543  ******************************************************************************/
544
545 void
546 AsReduceTypedefs (
547     char                    *Buffer,
548     char                    *Keyword)
549 {
550     char                    *SubString;
551     char                    *SubBuffer;
552     char                    *SubSubString;
553     int                     NestLevel;
554
555
556     SubBuffer = Buffer;
557     SubString = Buffer;
558
559     while (SubString)
560     {
561         SubString = strstr (SubBuffer, Keyword);
562
563         if (SubString)
564         {
565             SubSubString = SubString + strlen (Keyword);
566
567             /* skip spaces */
568
569             while (strchr(" \t\r\n", *SubSubString))
570             {
571                 SubSubString++;
572             }
573
574             /* skip type name */
575
576             while (!strchr(" \t\r\n", *SubSubString))
577             {
578                 SubSubString++;
579             }
580
581             /* skip spaces */
582
583             while (strchr(" \t\r\n", *SubSubString))
584             {
585                 SubSubString++;
586             }
587
588             if (*SubSubString == '{')
589             {
590                 /* Remove the typedef itself */
591
592                 SubBuffer = SubString + strlen ("typedef") + 1;
593                 (void) AsRemoveData (SubString, SubBuffer);
594
595                 /* Find the opening brace of the struct or union */
596
597                 while (*SubString != '{')
598                 {
599                     SubString++;
600                 }
601                 SubString++;
602
603                 /* Find the closing brace. Handles nested braces */
604
605                 NestLevel = 1;
606                 while (*SubString)
607                 {
608                     if (*SubString == '{')
609                     {
610                         NestLevel++;
611                     }
612                     else if (*SubString == '}')
613                     {
614                         NestLevel--;
615                     }
616
617                     SubString++;
618
619                     if (NestLevel == 0)
620                     {
621                         break;
622                     }
623                 }
624
625                 /* Remove an extra line feed if present */
626
627                 if (!strncmp (SubString - 3, "\n\n", 2))
628                 {
629                     *(SubString -2) = '}';
630                     SubString--;
631                 }
632
633                 /* Find the end of the typedef name */
634
635                 SubBuffer = AsSkipUntilChar (SubString, ';');
636
637                 /* And remove the typedef name */
638
639                 SubBuffer = AsRemoveData (SubString, SubBuffer);
640             }
641             else
642             {
643                 /* Skip the entire definition */
644
645                 SubString = strchr (SubString, ';') + 1;
646                 SubBuffer = SubString;
647             }
648         }
649     }
650 }
651
652
653 /******************************************************************************
654  *
655  * FUNCTION:    AsRemoveEmptyBlocks
656  *
657  * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This
658  *              can happen as a result of removing lines such as DEBUG_PRINT.
659  *
660  ******************************************************************************/
661
662 void
663 AsRemoveEmptyBlocks (
664     char                    *Buffer,
665     char                    *Filename)
666 {
667     char                    *SubBuffer;
668     char                    *BlockStart;
669     BOOLEAN                 EmptyBlock = TRUE;
670     BOOLEAN                 AnotherPassRequired = TRUE;
671     UINT32                  BlockCount = 0;
672
673
674     while (AnotherPassRequired)
675     {
676         SubBuffer = Buffer;
677         AnotherPassRequired = FALSE;
678
679         while (*SubBuffer)
680         {
681             if (*SubBuffer == '{')
682             {
683                 BlockStart = SubBuffer;
684                 EmptyBlock = TRUE;
685
686                 SubBuffer++;
687                 while (*SubBuffer != '}')
688                 {
689                     if ((*SubBuffer != ' ') &&
690                         (*SubBuffer != '\n'))
691                     {
692                         EmptyBlock = FALSE;
693                         break;
694                     }
695
696                     SubBuffer++;
697                 }
698
699                 if (EmptyBlock)
700                 {
701                     /* Find start of the first line of the block */
702
703                     while (*BlockStart != '\n')
704                     {
705                         BlockStart--;
706                     }
707
708                     /* Find end of the last line of the block */
709
710                     SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
711                     if (!SubBuffer)
712                     {
713                         break;
714                     }
715
716                     /* Remove the block */
717
718                     SubBuffer = AsRemoveData (BlockStart, SubBuffer);
719                     BlockCount++;
720                     AnotherPassRequired = TRUE;
721                     continue;
722                 }
723             }
724
725             SubBuffer++;
726         }
727     }
728
729     if (BlockCount)
730     {
731         Gbl_MadeChanges = TRUE;
732         AsPrint ("Code blocks deleted", BlockCount, Filename);
733     }
734 }
735
736
737 /******************************************************************************
738  *
739  * FUNCTION:    AsRemoveDebugMacros
740  *
741  * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output.
742  *
743  ******************************************************************************/
744
745 void
746 AsRemoveDebugMacros (
747     char                    *Buffer)
748 {
749     AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT");
750
751     AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT",      REPLACE_WHOLE_WORD);
752     AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW",  REPLACE_WHOLE_WORD);
753     AsRemoveStatement (Buffer, "DEBUG_EXEC",            REPLACE_WHOLE_WORD);
754     AsRemoveStatement (Buffer, "FUNCTION_ENTRY",        REPLACE_WHOLE_WORD);
755     AsRemoveStatement (Buffer, "PROC_NAME",             REPLACE_WHOLE_WORD);
756     AsRemoveStatement (Buffer, "FUNCTION_TRACE",        REPLACE_SUBSTRINGS);
757     AsRemoveStatement (Buffer, "DUMP_",                 REPLACE_SUBSTRINGS);
758
759     AsReplaceString ("return_VOID",         "return", REPLACE_WHOLE_WORD, Buffer);
760     AsReplaceString ("return_PTR",          "return", REPLACE_WHOLE_WORD, Buffer);
761     AsReplaceString ("return_STR",          "return", REPLACE_WHOLE_WORD, Buffer);
762     AsReplaceString ("return_ACPI_STATUS",  "return", REPLACE_WHOLE_WORD, Buffer);
763     AsReplaceString ("return_acpi_status",  "return", REPLACE_WHOLE_WORD, Buffer);
764     AsReplaceString ("return_VALUE",        "return", REPLACE_WHOLE_WORD, Buffer);
765 }
766
767
768 /******************************************************************************
769  *
770  * FUNCTION:    AsCleanupSpecialMacro
771  *
772  * DESCRIPTION: For special macro invocations (invoked without ";" at the end
773  *              of the lines), do the following:
774  *              1. Remove spaces appended by indent at the beginning of lines.
775  *              2. Add an empty line between two special macro invocations.
776  *
777  ******************************************************************************/
778
779 void
780 AsCleanupSpecialMacro (
781     char                    *Buffer,
782     char                    *Keyword)
783 {
784     char                    *SubString;
785     char                    *SubBuffer;
786     char                    *CommentEnd;
787     int                     NewLine;
788     int                     NestLevel;
789
790
791     SubBuffer = Buffer;
792     SubString = Buffer;
793
794     while (SubString)
795     {
796         SubString = strstr (SubBuffer, Keyword);
797
798         if (SubString)
799         {
800             /* Find start of the macro parameters */
801
802             while (*SubString != '(')
803             {
804                 SubString++;
805             }
806
807             SubString++;
808
809             NestLevel = 1;
810             while (*SubString)
811             {
812                 if (*SubString == '(')
813                 {
814                     NestLevel++;
815                 }
816                 else if (*SubString == ')')
817                 {
818                     NestLevel--;
819                 }
820
821                 SubString++;
822
823                 if (NestLevel == 0)
824                 {
825                     break;
826                 }
827             }
828
829 SkipLine:
830
831             /* Find end of the line */
832
833             NewLine = FALSE;
834             while (!NewLine && *SubString)
835             {
836                 if (*SubString == '\n' && *(SubString - 1) != '\\')
837                 {
838                     NewLine = TRUE;
839                 }
840
841                 SubString++;
842             }
843
844             /* Find end of the line */
845
846             if (*SubString == '#' || *SubString == '\n')
847             {
848                 goto SkipLine;
849             }
850
851             SubBuffer = SubString;
852
853             /* Find start of the non-space */
854
855             while (*SubString == ' ')
856             {
857                 SubString++;
858             }
859
860             /* Find end of the line */
861
862             if (*SubString == '#' || *SubString == '\n')
863             {
864                 goto SkipLine;
865             }
866
867             /* Find end of the line */
868
869             if (*SubString == '/' || *SubString == '*')
870             {
871                 CommentEnd = strstr (SubString, "*/");
872                 if (CommentEnd)
873                 {
874                     SubString = CommentEnd + 2;
875                     goto SkipLine;
876                 }
877             }
878
879             SubString = AsRemoveData (SubBuffer, SubString);
880         }
881     }
882 }