1 /******************************************************************************
2  *
3  * Module Name: asconvrt - Source conversion code
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2023, 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 AS_BRACE_INFO               Gbl_BraceInfo[] =
155 {
156     {" if",         3},
157     {" else if",    8},
158     {" else while", 11},
159     {" else",       5},
160     {" do ",        4},
161     {NULL,          0}
162 };
163 
164 
165 /* Local prototypes */
166 
167 static char *
168 AsMatchValidToken (
169     char                    *Buffer,
170     char                    *Filename,
171     char                    TargetChar,
172     AS_SCAN_CALLBACK        Callback);
173 
174 static char *
175 AsCheckBracesCallback (
176     char                    *Buffer,
177     char                    *Filename,
178     UINT32                  LineNumber);
179 
180 static UINT32
181 AsCountLines (
182     char                    *Buffer,
183     char                    *Filename);
184 
185 
186 #define MODULE_HEADER_BEGIN "/******************************************************************************\n *\n * Module Name:";
187 #define MODULE_HEADER_END   " *****************************************************************************/\n\n"
188 #define INTEL_COPYRIGHT     " * Copyright (C) 2000 - 2023, Intel Corp.\n"
189 
190 /* Opening signature of the Intel legal header */
191 
192 char        *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice";
193 
194 UINT32      NonAnsiCommentCount;
195 
196 char        CopyRightHeaderEnd[] = INTEL_COPYRIGHT " *\n" MODULE_HEADER_END;
197 
198 /******************************************************************************
199  *
200  * FUNCTION:    AsCountNonAnsiComments
201  *
202  * DESCRIPTION: Count the number of "//" comments. This type of comment is
203  *              non-ANSI C.
204  *
205  * NOTE: July 2014: Allows // within quoted strings and within normal
206  *       comments. Eliminates extraneous warnings from this utility.
207  *
208  ******************************************************************************/
209 
210 void
AsCountNonAnsiComments(char * Buffer,char * Filename)211 AsCountNonAnsiComments (
212     char                    *Buffer,
213     char                    *Filename)
214 {
215 
216     AsMatchValidToken (Buffer, Filename, 0, NULL);
217 
218     /* Error if any slash-slash comments found */
219 
220     if (NonAnsiCommentCount)
221     {
222         AsPrint ("Non-ANSI // Comments Found", NonAnsiCommentCount, Filename);
223         Gbl_NonAnsiComments += NonAnsiCommentCount;
224     }
225 }
226 
227 
228 /******************************************************************************
229  *
230  * FUNCTION:    AsCheckForBraces
231  *
232  * DESCRIPTION: Check for an open brace after each if/else/do (etc.)
233  *              statement
234  *
235  ******************************************************************************/
236 
237 void
AsCheckForBraces(char * Buffer,char * Filename)238 AsCheckForBraces (
239     char                    *Buffer,
240     char                    *Filename)
241 {
242 
243     AsMatchValidToken (Buffer, Filename, 0, AsCheckBracesCallback);
244 }
245 
246 
247 /******************************************************************************
248  *
249  * FUNCTION:    AsCheckBracesCallback
250  *
251  * DESCRIPTION: Check if/else/do statements. Ensure that braces
252  *              are always used.
253  *
254  * TBD: Currently, don't check while() statements. The problem is that there
255  * are two forms: do {} while (); and while () {}.
256  *
257  ******************************************************************************/
258 
259 static char *
AsCheckBracesCallback(char * Buffer,char * Filename,UINT32 LineNumber)260 AsCheckBracesCallback (
261     char                    *Buffer,
262     char                    *Filename,
263     UINT32                  LineNumber)
264 {
265     char                    *SubBuffer = Buffer;
266     char                    *NextBrace;
267     char                    *NextSemicolon;
268     AS_BRACE_INFO           *BraceInfo;
269 
270 
271     for (BraceInfo = Gbl_BraceInfo; BraceInfo->Operator; BraceInfo++)
272     {
273         if (!(strncmp (BraceInfo->Operator, SubBuffer, BraceInfo->Length)))
274         {
275             SubBuffer += (BraceInfo->Length - 1);
276 
277             /* Find next brace and the next semicolon */
278 
279             NextBrace = AsMatchValidToken (SubBuffer, Filename, '{', NULL);
280             NextSemicolon = AsMatchValidToken (SubBuffer, Filename, ';', NULL);
281 
282             /* Next brace should appear before next semicolon */
283 
284             if ((!NextBrace) ||
285                (NextSemicolon && (NextBrace > NextSemicolon)))
286             {
287                 Gbl_MissingBraces++;
288 
289                 if (!Gbl_QuietMode)
290                 {
291                     printf ("Missing braces for <%s>, line %u: %s\n",
292                         BraceInfo->Operator + 1, LineNumber, Filename);
293                 }
294             }
295 
296             return (SubBuffer);
297         }
298     }
299 
300     /* No match, just return original buffer */
301 
302     return (Buffer);
303 }
304 
305 
306 /******************************************************************************
307  *
308  * FUNCTION:    AsMatchValidToken
309  *
310  * DESCRIPTION: Find the next matching token in the input buffer.
311  *
312  ******************************************************************************/
313 
314 static char *
AsMatchValidToken(char * Buffer,char * Filename,char TargetChar,AS_SCAN_CALLBACK Callback)315 AsMatchValidToken (
316     char                    *Buffer,
317     char                    *Filename,
318     char                    TargetChar,
319     AS_SCAN_CALLBACK        Callback)
320 {
321     char                    *SubBuffer = Buffer;
322     char                    *StringStart;
323     UINT32                  TotalLines;
324 
325 
326     TotalLines = 1;
327     NonAnsiCommentCount = 0;
328 
329     /* Scan from current position up to the end if necessary */
330 
331     while (*SubBuffer)
332     {
333         /* Skip normal comments */
334 
335         if ((*SubBuffer == '/') &&
336             (*(SubBuffer + 1) == '*'))
337         {
338             /* Must maintain line count */
339 
340             SubBuffer += 2;
341             while (strncmp ("*/", SubBuffer, 2))
342             {
343                 if (*SubBuffer == '\n')
344                 {
345                     TotalLines++;
346                 }
347                 SubBuffer++;
348             }
349 
350             SubBuffer += 2;
351             continue;
352         }
353 
354         /* Skip single quoted chars */
355 
356         if (*SubBuffer == '\'')
357         {
358             SubBuffer++;
359             if (!(*SubBuffer))
360             {
361                 break;
362             }
363 
364             if (*SubBuffer == '\\')
365             {
366                 SubBuffer++;
367             }
368 
369             SubBuffer++;
370             continue;
371         }
372 
373         /* Skip quoted strings */
374 
375         if (*SubBuffer == '"')
376         {
377             StringStart = SubBuffer;
378             SubBuffer++;
379             if (!(*SubBuffer))
380             {
381                 break;
382             }
383 
384             while (*SubBuffer != '"')
385             {
386                 if ((*SubBuffer == '\n') ||
387                     (!(*SubBuffer)))
388                 {
389                     AsPrint ("Unbalanced quoted string",1, Filename);
390                     printf ("    %.32s (line %u)\n", StringStart, TotalLines);
391                     break;
392                 }
393 
394                 /* Handle escapes within the string */
395 
396                 if (*SubBuffer == '\\')
397                 {
398                     SubBuffer++;
399                 }
400 
401                 SubBuffer++;
402             }
403 
404             SubBuffer++;
405             continue;
406         }
407 
408         /* Now we can check for a slash-slash comment */
409 
410         if ((*SubBuffer == '/') &&
411             (*(SubBuffer + 1) == '/'))
412         {
413             NonAnsiCommentCount++;
414 
415             /* Skip to end-of-line */
416 
417             while ((*SubBuffer != '\n') &&
418                 (*SubBuffer))
419             {
420                 SubBuffer++;
421             }
422 
423             if (!(*SubBuffer))
424             {
425                 break;
426             }
427 
428             if (*SubBuffer == '\n')
429             {
430                 TotalLines++;
431             }
432 
433             SubBuffer++;
434             continue;
435         }
436 
437         /* Finally, check for a newline */
438 
439         if (*SubBuffer == '\n')
440         {
441             TotalLines++;
442             SubBuffer++;
443             continue;
444         }
445 
446         /* Normal character, do the user actions */
447 
448         if (Callback)
449         {
450             SubBuffer = Callback (SubBuffer, Filename, TotalLines);
451         }
452 
453         if (TargetChar && (*SubBuffer == TargetChar))
454         {
455             return (SubBuffer);
456         }
457 
458         SubBuffer++;
459     }
460 
461     return (NULL);
462 }
463 
464 
465 /******************************************************************************
466  *
467  * FUNCTION:    AsRemoveExtraLines
468  *
469  * DESCRIPTION: Remove all extra lines at the start and end of the file.
470  *
471  ******************************************************************************/
472 
473 void
AsRemoveExtraLines(char * FileBuffer,char * Filename)474 AsRemoveExtraLines (
475     char                    *FileBuffer,
476     char                    *Filename)
477 {
478     char                    *FileEnd;
479     int                     Length;
480 
481 
482     /* Remove any extra lines at the start of the file */
483 
484     while (*FileBuffer == '\n')
485     {
486         printf ("Removing extra line at start of file: %s\n", Filename);
487         AsRemoveData (FileBuffer, FileBuffer + 1);
488     }
489 
490     /* Remove any extra lines at the end of the file */
491 
492     Length = strlen (FileBuffer);
493     FileEnd = FileBuffer + (Length - 2);
494 
495     while (*FileEnd == '\n')
496     {
497         printf ("Removing extra line at end of file: %s\n", Filename);
498         AsRemoveData (FileEnd, FileEnd + 1);
499         FileEnd--;
500     }
501 }
502 
503 
504 /******************************************************************************
505  *
506  * FUNCTION:    AsRemoveSpacesAfterPeriod
507  *
508  * DESCRIPTION: Remove an extra space after a period.
509  *
510  ******************************************************************************/
511 
512 void
AsRemoveSpacesAfterPeriod(char * FileBuffer,char * Filename)513 AsRemoveSpacesAfterPeriod (
514     char                    *FileBuffer,
515     char                    *Filename)
516 {
517     int                     ReplaceCount = 0;
518     char                    *Possible;
519 
520 
521     Possible = FileBuffer;
522     while (Possible)
523     {
524         Possible = strstr (Possible, ".  ");
525         if (Possible)
526         {
527             if ((*(Possible -1) == '.')  ||
528                 (*(Possible -1) == '\"') ||
529                 (*(Possible -1) == '\n'))
530             {
531                 Possible += 3;
532                 continue;
533             }
534 
535             Possible = AsReplaceData (Possible, 3, ". ", 2);
536             ReplaceCount++;
537         }
538     }
539 
540     if (ReplaceCount)
541     {
542         printf ("Removed %d extra blanks after a period: %s\n",
543             ReplaceCount, Filename);
544     }
545 }
546 
547 
548 /******************************************************************************
549  *
550  * FUNCTION:    AsMatchExactWord
551  *
552  * DESCRIPTION: Check previous and next characters for whitespace
553  *
554  ******************************************************************************/
555 
556 BOOLEAN
AsMatchExactWord(char * Word,UINT32 WordLength)557 AsMatchExactWord (
558     char                    *Word,
559     UINT32                  WordLength)
560 {
561     char                    NextChar;
562     char                    PrevChar;
563 
564 
565     NextChar = Word[WordLength];
566     PrevChar = * (Word -1);
567 
568     if (isalnum ((int) NextChar) ||
569         (NextChar == '_')  ||
570         isalnum ((int) PrevChar) ||
571         (PrevChar == '_'))
572     {
573         return (FALSE);
574     }
575 
576     return (TRUE);
577 }
578 
579 
580 /******************************************************************************
581  *
582  * FUNCTION:    AsPrint
583  *
584  * DESCRIPTION: Common formatted print
585  *
586  ******************************************************************************/
587 
588 void
AsPrint(char * Message,UINT32 Count,char * Filename)589 AsPrint (
590     char                    *Message,
591     UINT32                  Count,
592     char                    *Filename)
593 {
594 
595     if (Gbl_QuietMode)
596     {
597         return;
598     }
599 
600     printf ("-- %4u %28.28s : %s\n", Count, Message, Filename);
601 }
602 
603 
604 /******************************************************************************
605  *
606  * FUNCTION:    AsTrimLines
607  *
608  * DESCRIPTION: Remove extra blanks from the end of source lines. Does not
609  *              check for tabs.
610  *
611  ******************************************************************************/
612 
613 void
AsTrimLines(char * Buffer,char * Filename)614 AsTrimLines (
615     char                    *Buffer,
616     char                    *Filename)
617 {
618     char                    *SubBuffer = Buffer;
619     char                    *StartWhiteSpace = NULL;
620     UINT32                  SpaceCount = 0;
621 
622 
623     while (*SubBuffer)
624     {
625         while (*SubBuffer != '\n')
626         {
627             if (!*SubBuffer)
628             {
629                 goto Exit;
630             }
631 
632             if (*SubBuffer == ' ')
633             {
634                 if (!StartWhiteSpace)
635                 {
636                     StartWhiteSpace = SubBuffer;
637                 }
638             }
639             else
640             {
641                 StartWhiteSpace = NULL;
642             }
643 
644             SubBuffer++;
645         }
646 
647         if (StartWhiteSpace)
648         {
649             SpaceCount += (SubBuffer - StartWhiteSpace);
650 
651             /* Remove the spaces */
652 
653             SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer);
654             StartWhiteSpace = NULL;
655         }
656 
657         SubBuffer++;
658     }
659 
660 
661 Exit:
662     if (SpaceCount)
663     {
664         Gbl_MadeChanges = TRUE;
665         AsPrint ("Extraneous spaces removed", SpaceCount, Filename);
666     }
667 }
668 
669 
670 /******************************************************************************
671  *
672  * FUNCTION:    AsTrimWhitespace
673  *
674  * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines.
675  *              this can happen during the translation when lines are removed.
676  *
677  ******************************************************************************/
678 
679 void
AsTrimWhitespace(char * Buffer)680 AsTrimWhitespace (
681     char                    *Buffer)
682 {
683     char                    *SubBuffer;
684     int                     ReplaceCount = 1;
685 
686 
687     while (ReplaceCount)
688     {
689         ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n",
690             REPLACE_SUBSTRINGS, Buffer);
691     }
692 
693     /*
694      * Check for exactly one blank line after the copyright header
695      */
696 
697     /* Find the header */
698 
699     SubBuffer = strstr (Buffer, HeaderBegin);
700     if (!SubBuffer)
701     {
702         return;
703     }
704 
705     /* Find the end of the header */
706 
707     SubBuffer = strstr (SubBuffer, "*/");
708     SubBuffer = AsSkipPastChar (SubBuffer, '\n');
709 
710     /* Replace a double blank line with a single */
711 
712     if (!strncmp (SubBuffer, "\n\n", 2))
713     {
714         AsReplaceData (SubBuffer, 2, "\n", 1);
715         AcpiOsPrintf ("Found multiple blank lines after copyright\n");
716     }
717 
718     /* If no blank line after header, insert one */
719 
720     else if (*SubBuffer != '\n')
721     {
722         AsInsertData (SubBuffer, "\n", 1);
723         AcpiOsPrintf ("Inserted blank line after copyright\n");
724     }
725 }
726 
727 
728 /******************************************************************************
729  *
730  * FUNCTION:    AsReplaceHeader
731  *
732  * DESCRIPTION: Replace the default Intel legal header with a new header
733  *
734  ******************************************************************************/
735 
736 void
AsReplaceHeader(char * Buffer,char * NewHeader)737 AsReplaceHeader (
738     char                    *Buffer,
739     char                    *NewHeader)
740 {
741     char                    *SubBuffer;
742     char                    *TokenEnd;
743 
744 
745     /* Find the original header */
746 
747     SubBuffer = strstr (Buffer, HeaderBegin);
748     if (!SubBuffer)
749     {
750         return;
751     }
752 
753     /* Find the end of the original header */
754 
755     TokenEnd = strstr (SubBuffer, "*/");
756     TokenEnd = AsSkipPastChar (TokenEnd, '\n');
757 
758     /* Delete old header, insert new one */
759 
760     AsReplaceData (SubBuffer, TokenEnd - SubBuffer,
761         NewHeader, strlen (NewHeader));
762 }
763 
764 
765 /******************************************************************************
766  *
767  * FUNCTION:    AsDoSpdxHeader
768  *
769  * DESCRIPTION: Replace the default Intel legal header with a new header
770  *
771  ******************************************************************************/
772 
773 void
AsDoSpdxHeader(char * Buffer,char * SpdxHeader)774 AsDoSpdxHeader (
775     char                    *Buffer,
776     char                    *SpdxHeader)
777 {
778     char                    *SubBuffer;
779 
780 
781     /* Place an SPDX header at the very top */
782 
783     AsReplaceData (Buffer, 0,
784         SpdxHeader, strlen (SpdxHeader));
785 
786     /* Place an Intel copyright notice in the module header */
787 
788     SubBuffer = strstr (Buffer, MODULE_HEADER_END);
789     if (!SubBuffer)
790     {
791         return;
792     }
793 
794     AsReplaceData (SubBuffer, strlen (MODULE_HEADER_END),
795         CopyRightHeaderEnd, strlen (CopyRightHeaderEnd));
796 }
797 
798 /******************************************************************************
799  *
800  * FUNCTION:    AsReplaceString
801  *
802  * DESCRIPTION: Replace all instances of a target string with a replacement
803  *              string. Returns count of the strings replaced.
804  *
805  ******************************************************************************/
806 
807 int
AsReplaceString(char * Target,char * Replacement,UINT8 Type,char * Buffer)808 AsReplaceString (
809     char                    *Target,
810     char                    *Replacement,
811     UINT8                   Type,
812     char                    *Buffer)
813 {
814     char                    *SubString1;
815     char                    *SubString2;
816     char                    *SubBuffer;
817     int                     TargetLength;
818     int                     ReplacementLength;
819     int                     ReplaceCount = 0;
820 
821 
822     TargetLength = strlen (Target);
823     ReplacementLength = strlen (Replacement);
824 
825     SubBuffer = Buffer;
826     SubString1 = Buffer;
827 
828     while (SubString1)
829     {
830         /* Find the target string */
831 
832         SubString1 = strstr (SubBuffer, Target);
833         if (!SubString1)
834         {
835             return (ReplaceCount);
836         }
837 
838         /*
839          * Check for translation escape string -- means to ignore
840          * blocks of code while replacing
841          */
842         if (Gbl_IgnoreTranslationEscapes)
843         {
844             SubString2 = NULL;
845         }
846         else
847         {
848             SubString2 = strstr (SubBuffer, AS_START_IGNORE);
849         }
850 
851         if ((SubString2) &&
852             (SubString2 < SubString1))
853         {
854             /* Find end of the escape block starting at "Substring2" */
855 
856             SubString2 = strstr (SubString2, AS_STOP_IGNORE);
857             if (!SubString2)
858             {
859                 /* Didn't find terminator */
860 
861                 return (ReplaceCount);
862             }
863 
864             /* Move buffer to end of escape block and continue */
865 
866             SubBuffer = SubString2;
867         }
868 
869         /* Do the actual replace if the target was found */
870 
871         else
872         {
873             if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD)
874             {
875                 if (!AsMatchExactWord (SubString1, TargetLength))
876                 {
877                     SubBuffer = SubString1 + 1;
878                     continue;
879                 }
880             }
881 
882             SubBuffer = AsReplaceData (SubString1, TargetLength,
883                 Replacement, ReplacementLength);
884 
885             if ((Type & EXTRA_INDENT_C) &&
886                 (!Gbl_StructDefs))
887             {
888                 SubBuffer = AsInsertData (SubBuffer, "        ", 8);
889             }
890 
891             ReplaceCount++;
892         }
893     }
894 
895     return (ReplaceCount);
896 }
897 
898 
899 /******************************************************************************
900  *
901  * FUNCTION:    AsConvertToLineFeeds
902  *
903  * DESCRIPTION: Convert all CR/LF pairs to LF only.
904  *
905  ******************************************************************************/
906 
907 void
AsConvertToLineFeeds(char * Buffer)908 AsConvertToLineFeeds (
909     char                    *Buffer)
910 {
911     char                    *SubString;
912     char                    *SubBuffer;
913 
914 
915     SubBuffer = Buffer;
916     SubString = Buffer;
917 
918     while (SubString)
919     {
920         /* Find the target string */
921 
922         SubString = strstr (SubBuffer, "\r\n");
923         if (!SubString)
924         {
925             return;
926         }
927 
928         SubBuffer = AsReplaceData (SubString, 1, NULL, 0);
929     }
930 }
931 
932 
933 /******************************************************************************
934  *
935  * FUNCTION:    AsInsertCarriageReturns
936  *
937  * DESCRIPTION: Convert lone LFs to CR/LF pairs.
938  *
939  ******************************************************************************/
940 
941 void
AsInsertCarriageReturns(char * Buffer)942 AsInsertCarriageReturns (
943     char                    *Buffer)
944 {
945     char                    *SubString;
946     char                    *SubBuffer;
947 
948 
949     SubBuffer = Buffer;
950     SubString = Buffer;
951 
952     while (SubString)
953     {
954         /* Find the target string */
955 
956         SubString = strstr (SubBuffer, "\n");
957         if (!SubString)
958         {
959             return;
960         }
961 
962         SubBuffer = AsInsertData (SubString, "\r", 1);
963         SubBuffer += 1;
964     }
965 }
966 
967 
968 /******************************************************************************
969  *
970  * FUNCTION:    AsBracesOnSameLine
971  *
972  * DESCRIPTION: Move opening braces up to the same line as an if, for, else,
973  *              or while statement (leave function opening brace on separate
974  *              line).
975  *
976  ******************************************************************************/
977 
978 void
AsBracesOnSameLine(char * Buffer)979 AsBracesOnSameLine (
980     char                    *Buffer)
981 {
982     char                    *SubBuffer = Buffer;
983     char                    *Beginning;
984     char                    *StartOfThisLine;
985     char                    *Next;
986     BOOLEAN                 BlockBegin = TRUE;
987 
988 
989     while (*SubBuffer)
990     {
991         /* Ignore comments */
992 
993         if ((SubBuffer[0] == '/') &&
994             (SubBuffer[1] == '*'))
995         {
996             SubBuffer = strstr (SubBuffer, "*/");
997             if (!SubBuffer)
998             {
999                 return;
1000             }
1001 
1002             SubBuffer += 2;
1003             continue;
1004         }
1005 
1006         /* Ignore quoted strings */
1007 
1008         if (*SubBuffer == '\"')
1009         {
1010             SubBuffer++;
1011             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
1012             if (!SubBuffer)
1013             {
1014                 return;
1015             }
1016         }
1017 
1018         if (!strncmp ("\n}", SubBuffer, 2))
1019         {
1020             /*
1021              * A newline followed by a closing brace closes a function
1022              * or struct or initializer block
1023              */
1024             BlockBegin = TRUE;
1025         }
1026 
1027         /*
1028          * Move every standalone brace up to the previous line
1029          * Check for digit will ignore initializer lists surrounded by braces.
1030          * This will work until we we need more complex detection.
1031          */
1032         if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1]))
1033         {
1034             if (BlockBegin)
1035             {
1036                 BlockBegin = FALSE;
1037             }
1038             else
1039             {
1040                 /*
1041                  * Backup to previous non-whitespace
1042                  */
1043                 Beginning = SubBuffer - 1;
1044                 while ((*Beginning == ' ')   ||
1045                        (*Beginning == '\n'))
1046                 {
1047                     Beginning--;
1048                 }
1049 
1050                 StartOfThisLine = Beginning;
1051                 while (*StartOfThisLine != '\n')
1052                 {
1053                     StartOfThisLine--;
1054                 }
1055 
1056                 /*
1057                  * Move the brace up to the previous line, UNLESS:
1058                  *
1059                  * 1) There is a conditional compile on the line (starts with '#')
1060                  * 2) Previous line ends with an '=' (Start of initializer block)
1061                  * 3) Previous line ends with a comma (part of an init list)
1062                  * 4) Previous line ends with a backslash (part of a macro)
1063                  */
1064                 if ((StartOfThisLine[1] != '#') &&
1065                     (*Beginning != '\\') &&
1066                     (*Beginning != '/') &&
1067                     (*Beginning != '{') &&
1068                     (*Beginning != '=') &&
1069                     (*Beginning != ','))
1070                 {
1071                     Beginning++;
1072                     SubBuffer++;
1073 
1074                     Gbl_MadeChanges = TRUE;
1075 
1076 #ifdef ADD_EXTRA_WHITESPACE
1077                     AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
1078 #else
1079                     /* Find non-whitespace start of next line */
1080 
1081                     Next = SubBuffer + 1;
1082                     while ((*Next == ' ')   ||
1083                            (*Next == '\t'))
1084                     {
1085                         Next++;
1086                     }
1087 
1088                     /* Find non-whitespace start of this line */
1089 
1090                     StartOfThisLine++;
1091                     while ((*StartOfThisLine == ' ')   ||
1092                            (*StartOfThisLine == '\t'))
1093                     {
1094                         StartOfThisLine++;
1095                     }
1096 
1097                     /*
1098                      * Must be a single-line comment to need more whitespace
1099                      * Even then, we don't need more if the previous statement
1100                      * is an "else".
1101                      */
1102                     if ((Next[0] == '/')  &&
1103                         (Next[1] == '*')  &&
1104                         (Next[2] != '\n') &&
1105 
1106                         (!strncmp (StartOfThisLine, "else if", 7)     ||
1107                          !strncmp (StartOfThisLine, "else while", 10) ||
1108                           strncmp (StartOfThisLine, "else", 4)))
1109                     {
1110                         AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
1111                     }
1112                     else
1113                     {
1114                         AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2);
1115                     }
1116 #endif
1117                 }
1118             }
1119         }
1120 
1121         SubBuffer++;
1122     }
1123 }
1124 
1125 
1126 /******************************************************************************
1127  *
1128  * FUNCTION:    AsTabify4
1129  *
1130  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
1131  *              preserved.
1132  *
1133  ******************************************************************************/
1134 
1135 void
AsTabify4(char * Buffer)1136 AsTabify4 (
1137     char                    *Buffer)
1138 {
1139     char                    *SubBuffer = Buffer;
1140     char                    *NewSubBuffer;
1141     UINT32                  SpaceCount = 0;
1142     UINT32                  Column = 0;
1143 
1144 
1145     while (*SubBuffer)
1146     {
1147         if (*SubBuffer == '\n')
1148         {
1149             Column = 0;
1150         }
1151         else
1152         {
1153             Column++;
1154         }
1155 
1156         /* Ignore comments */
1157 
1158         if ((SubBuffer[0] == '/') &&
1159             (SubBuffer[1] == '*'))
1160         {
1161             SubBuffer = strstr (SubBuffer, "*/");
1162             if (!SubBuffer)
1163             {
1164                 return;
1165             }
1166 
1167             SubBuffer += 2;
1168             continue;
1169         }
1170 
1171         /* Ignore quoted strings */
1172 
1173         if (*SubBuffer == '\"')
1174         {
1175             SubBuffer++;
1176             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
1177             if (!SubBuffer)
1178             {
1179                 return;
1180             }
1181             SpaceCount = 0;
1182         }
1183 
1184         if (*SubBuffer == ' ')
1185         {
1186             SpaceCount++;
1187 
1188             if (SpaceCount >= 4)
1189             {
1190                 SpaceCount = 0;
1191 
1192                 NewSubBuffer = (SubBuffer + 1) - 4;
1193                 *NewSubBuffer = '\t';
1194                 NewSubBuffer++;
1195 
1196                 /* Remove the spaces */
1197 
1198                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1);
1199             }
1200 
1201             if ((Column % 4) == 0)
1202             {
1203                 SpaceCount = 0;
1204             }
1205         }
1206         else
1207         {
1208             SpaceCount = 0;
1209         }
1210 
1211         SubBuffer++;
1212     }
1213 }
1214 
1215 
1216 /******************************************************************************
1217  *
1218  * FUNCTION:    AsTabify8
1219  *
1220  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
1221  *              preserved.
1222  *
1223  ******************************************************************************/
1224 
1225 void
AsTabify8(char * Buffer)1226 AsTabify8 (
1227     char                    *Buffer)
1228 {
1229     char                    *SubBuffer = Buffer;
1230     char                    *NewSubBuffer;
1231     char                    *CommentEnd = NULL;
1232     UINT32                  SpaceCount = 0;
1233     UINT32                  TabCount = 0;
1234     UINT32                  LastLineTabCount = 0;
1235     UINT32                  LastLineColumnStart = 0;
1236     UINT32                  ThisColumnStart = 0;
1237     UINT32                  ThisTabCount =  0;
1238     char                    *FirstNonBlank = NULL;
1239 
1240 
1241     while (*SubBuffer)
1242     {
1243         if (*SubBuffer == '\n')
1244         {
1245             /* This is a standalone blank line */
1246 
1247             FirstNonBlank = NULL;
1248             SpaceCount = 0;
1249             TabCount = 0;
1250             SubBuffer++;
1251             continue;
1252         }
1253 
1254         if (!FirstNonBlank)
1255         {
1256             /* Find the first non-blank character on this line */
1257 
1258             FirstNonBlank = SubBuffer;
1259             while (*FirstNonBlank == ' ')
1260             {
1261                 FirstNonBlank++;
1262             }
1263 
1264             /*
1265              * This mechanism limits the difference in tab counts from
1266              * line to line. It helps avoid the situation where a second
1267              * continuation line (which was indented correctly for tabs=4) would
1268              * get indented off the screen if we just blindly converted to tabs.
1269              */
1270             ThisColumnStart = FirstNonBlank - SubBuffer;
1271 
1272             if (LastLineTabCount == 0)
1273             {
1274                 ThisTabCount = 0;
1275             }
1276             else if (ThisColumnStart == LastLineColumnStart)
1277             {
1278                 ThisTabCount = LastLineTabCount -1;
1279             }
1280             else
1281             {
1282                 ThisTabCount = LastLineTabCount + 1;
1283             }
1284         }
1285 
1286         /* Check if we are in a comment */
1287 
1288         if ((SubBuffer[0] == '*') &&
1289             (SubBuffer[1] == '/'))
1290         {
1291             SpaceCount = 0;
1292             SubBuffer += 2;
1293 
1294             if (*SubBuffer == '\n')
1295             {
1296                 if (TabCount > 0)
1297                 {
1298                     LastLineTabCount = TabCount;
1299                     TabCount = 0;
1300                 }
1301 
1302                 FirstNonBlank = NULL;
1303                 LastLineColumnStart = ThisColumnStart;
1304                 SubBuffer++;
1305             }
1306 
1307             continue;
1308         }
1309 
1310         /* Check for comment open */
1311 
1312         if ((SubBuffer[0] == '/') &&
1313             (SubBuffer[1] == '*'))
1314         {
1315             /* Find the end of the comment, it must exist */
1316 
1317             CommentEnd = strstr (SubBuffer, "*/");
1318             if (!CommentEnd)
1319             {
1320                 return;
1321             }
1322 
1323             /* Toss the rest of this line or single-line comment */
1324 
1325             while ((SubBuffer < CommentEnd) &&
1326                    (*SubBuffer != '\n'))
1327             {
1328                 SubBuffer++;
1329             }
1330 
1331             if (*SubBuffer == '\n')
1332             {
1333                 if (TabCount > 0)
1334                 {
1335                     LastLineTabCount = TabCount;
1336                     TabCount = 0;
1337                 }
1338 
1339                 FirstNonBlank = NULL;
1340                 LastLineColumnStart = ThisColumnStart;
1341             }
1342 
1343             SpaceCount = 0;
1344             continue;
1345         }
1346 
1347         /* Ignore quoted strings */
1348 
1349         if ((!CommentEnd) && (*SubBuffer == '\"'))
1350         {
1351             SubBuffer++;
1352             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
1353             if (!SubBuffer)
1354             {
1355                 return;
1356             }
1357 
1358             SpaceCount = 0;
1359         }
1360 
1361         if (*SubBuffer != ' ')
1362         {
1363             /* Not a space, skip to end of line */
1364 
1365             SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
1366             if (!SubBuffer)
1367             {
1368                 return;
1369             }
1370             if (TabCount > 0)
1371             {
1372                 LastLineTabCount = TabCount;
1373                 TabCount = 0;
1374             }
1375 
1376             FirstNonBlank = NULL;
1377             LastLineColumnStart = ThisColumnStart;
1378             SpaceCount = 0;
1379         }
1380         else
1381         {
1382             /* Another space */
1383 
1384             SpaceCount++;
1385 
1386             if (SpaceCount >= 4)
1387             {
1388                 /* Replace this group of spaces with a tab character */
1389 
1390                 SpaceCount = 0;
1391 
1392                 NewSubBuffer = SubBuffer - 3;
1393 
1394                 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0)
1395                 {
1396                     *NewSubBuffer = '\t';
1397                     NewSubBuffer++;
1398                     SubBuffer++;
1399                     TabCount++;
1400                 }
1401 
1402                 /* Remove the spaces */
1403 
1404                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer);
1405                 continue;
1406             }
1407         }
1408 
1409         SubBuffer++;
1410     }
1411 }
1412 
1413 
1414 /******************************************************************************
1415  *
1416  * FUNCTION:    AsCountLines
1417  *
1418  * DESCRIPTION: Count the number of lines in the input buffer. Also count
1419  *              the number of long lines (lines longer than 80 chars).
1420  *
1421  ******************************************************************************/
1422 
1423 static UINT32
AsCountLines(char * Buffer,char * Filename)1424 AsCountLines (
1425     char                    *Buffer,
1426     char                    *Filename)
1427 {
1428     char                    *SubBuffer = Buffer;
1429     char                    *EndOfLine;
1430     UINT32                  LineCount = 0;
1431     UINT32                  LongLineCount = 0;
1432 
1433 
1434     while (*SubBuffer)
1435     {
1436         EndOfLine = AsSkipUntilChar (SubBuffer, '\n');
1437         if (!EndOfLine)
1438         {
1439             Gbl_TotalLines += LineCount;
1440             return (LineCount);
1441         }
1442 
1443         if ((EndOfLine - SubBuffer) > 80)
1444         {
1445             LongLineCount++;
1446             VERBOSE_PRINT (("long: %.80s\n", SubBuffer));
1447         }
1448 
1449         LineCount++;
1450         SubBuffer = EndOfLine + 1;
1451     }
1452 
1453     if (LongLineCount)
1454     {
1455         VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n",
1456             LongLineCount, Filename));
1457 
1458         Gbl_LongLines += LongLineCount;
1459     }
1460 
1461     Gbl_TotalLines += LineCount;
1462     return (LineCount);
1463 }
1464 
1465 
1466 /******************************************************************************
1467  *
1468  * FUNCTION:    AsCountTabs
1469  *
1470  * DESCRIPTION: Simply count the number of tabs in the input file buffer
1471  *
1472  ******************************************************************************/
1473 
1474 void
AsCountTabs(char * Buffer,char * Filename)1475 AsCountTabs (
1476     char                    *Buffer,
1477     char                    *Filename)
1478 {
1479     UINT32                  i;
1480     UINT32                  TabCount = 0;
1481 
1482 
1483     for (i = 0; Buffer[i]; i++)
1484     {
1485         if (Buffer[i] == '\t')
1486         {
1487             TabCount++;
1488         }
1489     }
1490 
1491     if (TabCount)
1492     {
1493         AsPrint ("Tabs found", TabCount, Filename);
1494         Gbl_Tabs += TabCount;
1495     }
1496 
1497     AsCountLines (Buffer, Filename);
1498 }
1499 
1500 
1501 /******************************************************************************
1502  *
1503  * FUNCTION:    AsCountSourceLines
1504  *
1505  * DESCRIPTION: Count the number of C source lines. Defined by 1) not a
1506  *              comment, and 2) not a blank line.
1507  *
1508  ******************************************************************************/
1509 
1510 void
AsCountSourceLines(char * Buffer,char * Filename)1511 AsCountSourceLines (
1512     char                    *Buffer,
1513     char                    *Filename)
1514 {
1515     char                    *SubBuffer = Buffer;
1516     UINT32                  LineCount = 0;
1517     UINT32                  WhiteCount = 0;
1518     UINT32                  CommentCount = 0;
1519 
1520 
1521     while (*SubBuffer)
1522     {
1523         /* Detect comments (// comments are not used, non-ansii) */
1524 
1525         if ((SubBuffer[0] == '/') &&
1526             (SubBuffer[1] == '*'))
1527         {
1528             SubBuffer += 2;
1529 
1530             /* First line of multi-line comment is often just whitespace */
1531 
1532             if (SubBuffer[0] == '\n')
1533             {
1534                 WhiteCount++;
1535                 SubBuffer++;
1536             }
1537             else
1538             {
1539                 CommentCount++;
1540             }
1541 
1542             /* Find end of comment */
1543 
1544             while (SubBuffer[0] && SubBuffer[1] &&
1545                 !(((SubBuffer[0] == '*') &&
1546                     (SubBuffer[1] == '/'))))
1547             {
1548                 if (SubBuffer[0] == '\n')
1549                 {
1550                     CommentCount++;
1551                 }
1552 
1553                 SubBuffer++;
1554             }
1555         }
1556 
1557         /* A linefeed followed by a non-linefeed is a valid source line */
1558 
1559         else if ((SubBuffer[0] == '\n') &&
1560                  (SubBuffer[1] != '\n'))
1561         {
1562             LineCount++;
1563         }
1564 
1565         /* Two back-to-back linefeeds indicate a whitespace line */
1566 
1567         else if ((SubBuffer[0] == '\n') &&
1568                  (SubBuffer[1] == '\n'))
1569         {
1570             WhiteCount++;
1571         }
1572 
1573         SubBuffer++;
1574     }
1575 
1576     /* Adjust comment count for legal header */
1577 
1578     if (Gbl_HeaderSize < CommentCount)
1579     {
1580         CommentCount -= Gbl_HeaderSize;
1581         Gbl_HeaderLines += Gbl_HeaderSize;
1582     }
1583 
1584     Gbl_SourceLines += LineCount;
1585     Gbl_WhiteLines += WhiteCount;
1586     Gbl_CommentLines += CommentCount;
1587 
1588     VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n",
1589         CommentCount, WhiteCount, LineCount,
1590         LineCount + WhiteCount + CommentCount, Filename));
1591 }
1592 
1593 
1594 /******************************************************************************
1595  *
1596  * FUNCTION:    AsInsertPrefix
1597  *
1598  * DESCRIPTION: Insert struct or union prefixes
1599  *
1600  ******************************************************************************/
1601 
1602 void
AsInsertPrefix(char * Buffer,char * Keyword,UINT8 Type)1603 AsInsertPrefix (
1604     char                    *Buffer,
1605     char                    *Keyword,
1606     UINT8                   Type)
1607 {
1608     char                    *SubString;
1609     char                    *SubBuffer;
1610     char                    *EndKeyword;
1611     int                     InsertLength;
1612     char                    *InsertString;
1613     int                     TrailingSpaces;
1614     char                    LowerKeyword[128];
1615     int                     KeywordLength;
1616     char                    *LineStart;
1617     BOOLEAN                 FoundPrefix;
1618 
1619 
1620     switch (Type)
1621     {
1622     case SRC_TYPE_STRUCT:
1623 
1624         InsertString = "struct ";
1625         break;
1626 
1627     case SRC_TYPE_UNION:
1628 
1629         InsertString = "union ";
1630         break;
1631 
1632     default:
1633 
1634         return;
1635     }
1636 
1637     strcpy (LowerKeyword, Keyword);
1638     AcpiUtStrlwr (LowerKeyword);
1639 
1640     SubBuffer = Buffer;
1641     SubString = Buffer;
1642     InsertLength = strlen (InsertString);
1643     KeywordLength = strlen (Keyword);
1644 
1645 
1646     while (SubString)
1647     {
1648         /* Find an instance of the keyword */
1649 
1650         SubString = strstr (SubBuffer, LowerKeyword);
1651         if (!SubString)
1652         {
1653             return;
1654         }
1655 
1656         SubBuffer = SubString;
1657 
1658         /* Must be standalone word, not a substring */
1659 
1660         if (AsMatchExactWord (SubString, KeywordLength))
1661         {
1662             /* Make sure the keyword isn't already prefixed with the insert */
1663 
1664             /* We find the beginning of the line and try to find the InsertString
1665              * from LineStart up to SubBuffer (our keyword). If it's not there,
1666              * we assume it doesn't have a prefix; this is a limitation, as having
1667              * a keyword on another line is absolutely valid C.
1668              */
1669 
1670             LineStart = SubString;
1671             FoundPrefix = FALSE;
1672 
1673             /* Find the start of the line */
1674 
1675             while (LineStart > Buffer)
1676             {
1677                 if (*LineStart == '\n')
1678                 {
1679                     LineStart++;
1680                     break;
1681                 }
1682 
1683                 LineStart--;
1684             }
1685 
1686             /* Try to find InsertString from the start of the line up to SubBuffer */
1687             /* Note that this algorithm is a bit naive. */
1688 
1689             while (SubBuffer > LineStart)
1690             {
1691                 if (*LineStart != *InsertString)
1692                 {
1693                     LineStart++;
1694                     continue;
1695                 }
1696 
1697                 if (strncmp (LineStart++, InsertString, InsertLength))
1698                 {
1699                     continue;
1700                 }
1701 
1702                 FoundPrefix = TRUE;
1703                 LineStart += InsertLength - 1;
1704 
1705                 /* Now check if there's non-whitespace between InsertString and SubBuffer, as that
1706                  * means it's not a valid prefix in this case. */
1707 
1708                 while (LineStart != SubBuffer)
1709                 {
1710                     if (!strchr (" \t\r\n", *LineStart))
1711                     {
1712                         /* We found non-whitespace while traversing up to SubBuffer,
1713                          * so this isn't a prefix.
1714                          */
1715                         FoundPrefix = FALSE;
1716                         break;
1717                     }
1718 
1719                     LineStart++;
1720                 }
1721             }
1722 
1723             if (FoundPrefix)
1724             {
1725                 /* Add spaces if not already at the end-of-line */
1726 
1727                 if (*(SubBuffer + KeywordLength) != '\n')
1728                 {
1729                     /* Already present, add spaces after to align structure members */
1730 
1731 #if 0
1732 /* ONLY FOR C FILES */
1733                     AsInsertData (SubBuffer + KeywordLength, "        ", 8);
1734 #endif
1735                 }
1736                 goto Next;
1737             }
1738 
1739             /* Make sure the keyword isn't at the end of a struct/union */
1740             /* Note: This code depends on a single space after the brace */
1741 
1742             if (*(SubString - 2) == '}')
1743             {
1744                 goto Next;
1745             }
1746 
1747             /* Prefix the keyword with the insert string */
1748 
1749             Gbl_MadeChanges = TRUE;
1750 
1751             /* Is there room for insertion */
1752 
1753             EndKeyword = SubString + strlen (LowerKeyword);
1754 
1755             TrailingSpaces = 0;
1756             while (EndKeyword[TrailingSpaces] == ' ')
1757             {
1758                 TrailingSpaces++;
1759             }
1760 
1761             /*
1762              * Use "if (TrailingSpaces > 1)" if we want to ignore casts
1763              */
1764             SubBuffer = SubString + InsertLength;
1765 
1766             if (TrailingSpaces > InsertLength)
1767             {
1768                 /* Insert the keyword */
1769 
1770                 memmove (SubBuffer, SubString, KeywordLength);
1771 
1772                 /* Insert the keyword */
1773 
1774                 memmove (SubString, InsertString, InsertLength);
1775             }
1776             else
1777             {
1778                 AsInsertData (SubString, InsertString, InsertLength);
1779             }
1780         }
1781 
1782 Next:
1783         SubBuffer += KeywordLength;
1784     }
1785 }
1786 
1787 #ifdef ACPI_FUTURE_IMPLEMENTATION
1788 /******************************************************************************
1789  *
1790  * FUNCTION:    AsTrimComments
1791  *
1792  * DESCRIPTION: Finds 3-line comments with only a single line of text
1793  *
1794  ******************************************************************************/
1795 
1796 void
AsTrimComments(char * Buffer,char * Filename)1797 AsTrimComments (
1798     char                    *Buffer,
1799     char                    *Filename)
1800 {
1801     char                    *SubBuffer = Buffer;
1802     char                    *Ptr1;
1803     char                    *Ptr2;
1804     UINT32                  LineCount;
1805     UINT32                  ShortCommentCount = 0;
1806 
1807 
1808     while (1)
1809     {
1810         /* Find comment open, within procedure level */
1811 
1812         SubBuffer = strstr (SubBuffer, "    /*");
1813         if (!SubBuffer)
1814         {
1815             goto Exit;
1816         }
1817 
1818         /* Find comment terminator */
1819 
1820         Ptr1 = strstr (SubBuffer, "*/");
1821         if (!Ptr1)
1822         {
1823             goto Exit;
1824         }
1825 
1826         /* Find next EOL (from original buffer) */
1827 
1828         Ptr2 = strstr (SubBuffer, "\n");
1829         if (!Ptr2)
1830         {
1831             goto Exit;
1832         }
1833 
1834         /* Ignore one-line comments */
1835 
1836         if (Ptr1 < Ptr2)
1837         {
1838             /* Normal comment, ignore and continue; */
1839 
1840             SubBuffer = Ptr2;
1841             continue;
1842         }
1843 
1844         /* Examine multi-line comment */
1845 
1846         LineCount = 1;
1847         while (Ptr1 > Ptr2)
1848         {
1849             /* Find next EOL */
1850 
1851             Ptr2++;
1852             Ptr2 = strstr (Ptr2, "\n");
1853             if (!Ptr2)
1854             {
1855                 goto Exit;
1856             }
1857 
1858             LineCount++;
1859         }
1860 
1861         SubBuffer = Ptr1;
1862 
1863         if (LineCount <= 3)
1864         {
1865             ShortCommentCount++;
1866         }
1867     }
1868 
1869 
1870 Exit:
1871 
1872     if (ShortCommentCount)
1873     {
1874         AsPrint ("Short Comments found", ShortCommentCount, Filename);
1875     }
1876 }
1877 #endif
1878 
1879 #ifdef ACPI_UNUSED_FUNCTIONS
1880 /******************************************************************************
1881  *
1882  * FUNCTION:    AsCheckAndSkipLiterals
1883  *
1884  * DESCRIPTION: Generic routine to skip comments and quoted string literals.
1885  *              Keeps a line count.
1886  *
1887  ******************************************************************************/
1888 
1889 static char *
1890 AsCheckAndSkipLiterals (
1891     char                    *Buffer,
1892     UINT32                  *TotalLines);
1893 
1894 
1895 static char *
AsCheckAndSkipLiterals(char * Buffer,UINT32 * TotalLines)1896 AsCheckAndSkipLiterals (
1897     char                    *Buffer,
1898     UINT32                  *TotalLines)
1899 {
1900     UINT32                  NewLines = 0;
1901     char                    *SubBuffer = Buffer;
1902     char                    *LiteralEnd;
1903 
1904 
1905     /* Ignore comments */
1906 
1907     if ((SubBuffer[0] == '/') &&
1908         (SubBuffer[1] == '*'))
1909     {
1910         LiteralEnd = strstr (SubBuffer, "*/");
1911         SubBuffer += 2;     /* Get past comment opening */
1912 
1913         if (!LiteralEnd)
1914         {
1915             return (SubBuffer);
1916         }
1917 
1918         while (SubBuffer < LiteralEnd)
1919         {
1920             if (*SubBuffer == '\n')
1921             {
1922                 NewLines++;
1923             }
1924 
1925             SubBuffer++;
1926         }
1927 
1928         SubBuffer += 2;     /* Get past comment close */
1929     }
1930 
1931     /* Ignore quoted strings */
1932 
1933     else if (*SubBuffer == '\"')
1934     {
1935         SubBuffer++;
1936         LiteralEnd = AsSkipPastChar (SubBuffer, '\"');
1937         if (!LiteralEnd)
1938         {
1939             return (SubBuffer);
1940         }
1941     }
1942 
1943     if (TotalLines)
1944     {
1945         (*TotalLines) += NewLines;
1946     }
1947     return (SubBuffer);
1948 }
1949 #endif
1950