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