xref: /netbsd-src/sys/external/bsd/acpica/dist/tools/acpisrc/asconvrt.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 
2 /******************************************************************************
3  *
4  * Module Name: asconvrt - Source conversion code
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2011, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 #include "acpisrc.h"
46 
47 /* Local prototypes */
48 
49 char *
50 AsCheckAndSkipLiterals (
51     char                    *Buffer,
52     UINT32                  *TotalLines);
53 
54 UINT32
55 AsCountLines (
56     char                    *Buffer,
57     char                    *Filename);
58 
59 /* Opening signature of the Intel legal header */
60 
61 char        *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice";
62 
63 
64 /******************************************************************************
65  *
66  * FUNCTION:    AsMatchExactWord
67  *
68  * DESCRIPTION: Check previous and next characters for whitespace
69  *
70  ******************************************************************************/
71 
72 BOOLEAN
73 AsMatchExactWord (
74     char                    *Word,
75     UINT32                  WordLength)
76 {
77     char                    NextChar;
78     char                    PrevChar;
79 
80 
81     NextChar = Word[WordLength];
82     PrevChar = * (Word -1);
83 
84     if (isalnum ((int) NextChar) ||
85         (NextChar == '_')  ||
86         isalnum ((int) PrevChar) ||
87         (PrevChar == '_'))
88     {
89         return (FALSE);
90     }
91 
92     return (TRUE);
93 }
94 
95 
96 /******************************************************************************
97  *
98  * FUNCTION:    AsPrint
99  *
100  * DESCRIPTION: Common formatted print
101  *
102  ******************************************************************************/
103 
104 void
105 AsPrint (
106     char                    *Message,
107     UINT32                  Count,
108     char                    *Filename)
109 {
110 
111     if (Gbl_QuietMode)
112     {
113         return;
114     }
115 
116     printf ("-- %4u %28.28s : %s\n", Count, Message, Filename);
117 }
118 
119 
120 /******************************************************************************
121  *
122  * FUNCTION:    AsCheckAndSkipLiterals
123  *
124  * DESCRIPTION: Generic routine to skip comments and quoted string literals.
125  *              Keeps a line count.
126  *
127  ******************************************************************************/
128 
129 char *
130 AsCheckAndSkipLiterals (
131     char                    *Buffer,
132     UINT32                  *TotalLines)
133 {
134     UINT32                  NewLines = 0;
135     char                    *SubBuffer = Buffer;
136     char                    *LiteralEnd;
137 
138 
139     /* Ignore comments */
140 
141     if ((SubBuffer[0] == '/') &&
142         (SubBuffer[1] == '*'))
143     {
144         LiteralEnd = strstr (SubBuffer, "*/");
145         SubBuffer += 2;     /* Get past comment opening */
146 
147         if (!LiteralEnd)
148         {
149             return SubBuffer;
150         }
151 
152         while (SubBuffer < LiteralEnd)
153         {
154             if (*SubBuffer == '\n')
155             {
156                 NewLines++;
157             }
158 
159             SubBuffer++;
160         }
161 
162         SubBuffer += 2;     /* Get past comment close */
163     }
164 
165     /* Ignore quoted strings */
166 
167     else if (*SubBuffer == '\"')
168     {
169         SubBuffer++;
170         LiteralEnd = AsSkipPastChar (SubBuffer, '\"');
171         if (!LiteralEnd)
172         {
173             return SubBuffer;
174         }
175     }
176 
177     if (TotalLines)
178     {
179         (*TotalLines) += NewLines;
180     }
181     return SubBuffer;
182 }
183 
184 
185 /******************************************************************************
186  *
187  * FUNCTION:    AsAsCheckForBraces
188  *
189  * DESCRIPTION: Check for an open brace after each if statement
190  *
191  ******************************************************************************/
192 
193 void
194 AsCheckForBraces (
195     char                    *Buffer,
196     char                    *Filename)
197 {
198     char                    *SubBuffer = Buffer;
199     char                    *NextBrace;
200     char                    *NextSemicolon;
201     char                    *NextIf;
202     UINT32                  TotalLines = 1;
203 
204 
205     while (*SubBuffer)
206     {
207 
208         SubBuffer = AsCheckAndSkipLiterals (SubBuffer, &TotalLines);
209 
210         if (*SubBuffer == '\n')
211         {
212             TotalLines++;
213         }
214         else if (!(strncmp (" if", SubBuffer, 3)))
215         {
216             SubBuffer += 2;
217             NextBrace = strstr (SubBuffer, "{");
218             NextSemicolon = strstr (SubBuffer, ";");
219             NextIf = strstr (SubBuffer, " if");
220 
221             if ((!NextBrace) ||
222                (NextSemicolon && (NextBrace > NextSemicolon)) ||
223                (NextIf && (NextBrace > NextIf)))
224             {
225                 Gbl_MissingBraces++;
226 
227                 if (!Gbl_QuietMode)
228                 {
229                     printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename);
230                 }
231             }
232         }
233         else if (!(strncmp (" else if", SubBuffer, 8)))
234         {
235             SubBuffer += 7;
236             NextBrace = strstr (SubBuffer, "{");
237             NextSemicolon = strstr (SubBuffer, ";");
238             NextIf = strstr (SubBuffer, " if");
239 
240             if ((!NextBrace) ||
241                (NextSemicolon && (NextBrace > NextSemicolon)) ||
242                (NextIf && (NextBrace > NextIf)))
243             {
244                 Gbl_MissingBraces++;
245 
246                 if (!Gbl_QuietMode)
247                 {
248                     printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename);
249                 }
250             }
251         }
252         else if (!(strncmp (" else", SubBuffer, 5)))
253         {
254             SubBuffer += 4;
255             NextBrace = strstr (SubBuffer, "{");
256             NextSemicolon = strstr (SubBuffer, ";");
257             NextIf = strstr (SubBuffer, " if");
258 
259             if ((!NextBrace) ||
260                (NextSemicolon && (NextBrace > NextSemicolon)) ||
261                (NextIf && (NextBrace > NextIf)))
262             {
263                 Gbl_MissingBraces++;
264 
265                 if (!Gbl_QuietMode)
266                 {
267                     printf ("Missing braces for <else>, line %u: %s\n", TotalLines, Filename);
268                 }
269             }
270         }
271 
272         SubBuffer++;
273     }
274 }
275 
276 
277 /******************************************************************************
278  *
279  * FUNCTION:    AsTrimLines
280  *
281  * DESCRIPTION: Remove extra blanks from the end of source lines.  Does not
282  *              check for tabs.
283  *
284  ******************************************************************************/
285 
286 void
287 AsTrimLines (
288     char                    *Buffer,
289     char                    *Filename)
290 {
291     char                    *SubBuffer = Buffer;
292     char                    *StartWhiteSpace = NULL;
293     UINT32                  SpaceCount = 0;
294 
295 
296     while (*SubBuffer)
297     {
298         while (*SubBuffer != '\n')
299         {
300             if (!*SubBuffer)
301             {
302                 goto Exit;
303             }
304 
305             if (*SubBuffer == ' ')
306             {
307                 if (!StartWhiteSpace)
308                 {
309                     StartWhiteSpace = SubBuffer;
310                 }
311             }
312             else
313             {
314                 StartWhiteSpace = NULL;
315             }
316 
317             SubBuffer++;
318         }
319 
320         if (StartWhiteSpace)
321         {
322             SpaceCount += (SubBuffer - StartWhiteSpace);
323 
324             /* Remove the spaces */
325 
326             SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer);
327             StartWhiteSpace = NULL;
328         }
329 
330         SubBuffer++;
331     }
332 
333 
334 Exit:
335     if (SpaceCount)
336     {
337         Gbl_MadeChanges = TRUE;
338         AsPrint ("Extraneous spaces removed", SpaceCount, Filename);
339     }
340 }
341 
342 
343 /******************************************************************************
344  *
345  * FUNCTION:    AsTrimWhitespace
346  *
347  * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines.
348  *              this can happen during the translation when lines are removed.
349  *
350  ******************************************************************************/
351 
352 void
353 AsTrimWhitespace (
354     char                    *Buffer)
355 {
356     int                     ReplaceCount = 1;
357 
358 
359     while (ReplaceCount)
360     {
361         ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", REPLACE_SUBSTRINGS, Buffer);
362     }
363 }
364 
365 
366 /******************************************************************************
367  *
368  * FUNCTION:    AsReplaceHeader
369  *
370  * DESCRIPTION: Replace the default Intel legal header with a new header
371  *
372  ******************************************************************************/
373 
374 void
375 AsReplaceHeader (
376     char                    *Buffer,
377     char                    *NewHeader)
378 {
379     char                    *SubBuffer;
380     char                    *TokenEnd;
381 
382 
383     /* Find the original header */
384 
385     SubBuffer = strstr (Buffer, HeaderBegin);
386     if (!SubBuffer)
387     {
388         return;
389     }
390 
391     /* Find the end of the original header */
392 
393     TokenEnd = strstr (SubBuffer, "*/");
394     TokenEnd = AsSkipPastChar (TokenEnd, '\n');
395 
396     /* Delete old header, insert new one */
397 
398     AsReplaceData (SubBuffer, TokenEnd - SubBuffer, NewHeader, strlen (NewHeader));
399 }
400 
401 
402 /******************************************************************************
403  *
404  * FUNCTION:    AsReplaceString
405  *
406  * DESCRIPTION: Replace all instances of a target string with a replacement
407  *              string.  Returns count of the strings replaced.
408  *
409  ******************************************************************************/
410 
411 int
412 AsReplaceString (
413     char                    *Target,
414     char                    *Replacement,
415     UINT8                   Type,
416     char                    *Buffer)
417 {
418     char                    *SubString1;
419     char                    *SubString2;
420     char                    *SubBuffer;
421     int                     TargetLength;
422     int                     ReplacementLength;
423     int                     ReplaceCount = 0;
424 
425 
426     TargetLength = strlen (Target);
427     ReplacementLength = strlen (Replacement);
428 
429     SubBuffer = Buffer;
430     SubString1 = Buffer;
431 
432     while (SubString1)
433     {
434         /* Find the target string */
435 
436         SubString1 = strstr (SubBuffer, Target);
437         if (!SubString1)
438         {
439             return ReplaceCount;
440         }
441 
442         /*
443          * Check for translation escape string -- means to ignore
444          * blocks of code while replacing
445          */
446         SubString2 = strstr (SubBuffer, AS_START_IGNORE);
447 
448         if ((SubString2) &&
449             (SubString2 < SubString1))
450         {
451             /* Find end of the escape block starting at "Substring2" */
452 
453             SubString2 = strstr (SubString2, AS_STOP_IGNORE);
454             if (!SubString2)
455             {
456                 /* Didn't find terminator */
457 
458                 return ReplaceCount;
459             }
460 
461             /* Move buffer to end of escape block and continue */
462 
463             SubBuffer = SubString2;
464         }
465 
466         /* Do the actual replace if the target was found */
467 
468         else
469         {
470             if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD)
471             {
472                 if (!AsMatchExactWord (SubString1, TargetLength))
473                 {
474                     SubBuffer = SubString1 + 1;
475                     continue;
476                 }
477             }
478 
479             SubBuffer = AsReplaceData (SubString1, TargetLength, Replacement, ReplacementLength);
480 
481             if ((Type & EXTRA_INDENT_C) &&
482                 (!Gbl_StructDefs))
483             {
484                 SubBuffer = AsInsertData (SubBuffer, "        ", 8);
485             }
486 
487             ReplaceCount++;
488         }
489     }
490 
491     return ReplaceCount;
492 }
493 
494 
495 /******************************************************************************
496  *
497  * FUNCTION:    AsConvertToLineFeeds
498  *
499  * DESCRIPTION:
500  *
501  ******************************************************************************/
502 
503 void
504 AsConvertToLineFeeds (
505     char                    *Buffer)
506 {
507     char                    *SubString;
508     char                    *SubBuffer;
509 
510 
511     SubBuffer = Buffer;
512     SubString = Buffer;
513 
514     while (SubString)
515     {
516         /* Find the target string */
517 
518         SubString = strstr (SubBuffer, "\r\n");
519         if (!SubString)
520         {
521             return;
522         }
523 
524         SubBuffer = AsReplaceData (SubString, 1, NULL, 0);
525     }
526     return;
527 }
528 
529 
530 /******************************************************************************
531  *
532  * FUNCTION:    AsInsertCarriageReturns
533  *
534  * DESCRIPTION:
535  *
536  ******************************************************************************/
537 
538 void
539 AsInsertCarriageReturns (
540     char                    *Buffer)
541 {
542     char                    *SubString;
543     char                    *SubBuffer;
544 
545 
546     SubBuffer = Buffer;
547     SubString = Buffer;
548 
549     while (SubString)
550     {
551         /* Find the target string */
552 
553         SubString = strstr (SubBuffer, "\n");
554         if (!SubString)
555         {
556             return;
557         }
558 
559         SubBuffer = AsInsertData (SubString, "\r", 1);
560         SubBuffer += 1;
561     }
562     return;
563 }
564 
565 
566 /******************************************************************************
567  *
568  * FUNCTION:    AsBracesOnSameLine
569  *
570  * DESCRIPTION: Move opening braces up to the same line as an if, for, else,
571  *              or while statement (leave function opening brace on separate
572  *              line).
573  *
574  ******************************************************************************/
575 
576 void
577 AsBracesOnSameLine (
578     char                    *Buffer)
579 {
580     UINT32                  Length;
581     char                    *SubBuffer = Buffer;
582     char                    *Beginning;
583     char                    *StartOfThisLine;
584     char                    *Next;
585     BOOLEAN                 BlockBegin = TRUE;
586 
587 
588     while (*SubBuffer)
589     {
590         /* Ignore comments */
591 
592         if ((SubBuffer[0] == '/') &&
593             (SubBuffer[1] == '*'))
594         {
595             SubBuffer = strstr (SubBuffer, "*/");
596             if (!SubBuffer)
597             {
598                 return;
599             }
600 
601             SubBuffer += 2;
602             continue;
603         }
604 
605         /* Ignore quoted strings */
606 
607         if (*SubBuffer == '\"')
608         {
609             SubBuffer++;
610             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
611             if (!SubBuffer)
612             {
613                 return;
614             }
615         }
616 
617         if (!strncmp ("\n}", SubBuffer, 2))
618         {
619             /*
620              * A newline followed by a closing brace closes a function
621              * or struct or initializer block
622              */
623             BlockBegin = TRUE;
624         }
625 
626         /*
627          * Move every standalone brace up to the previous line
628          * Check for digit will ignore initializer lists surrounded by braces.
629          * This will work until we we need more complex detection.
630          */
631         if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1]))
632         {
633             if (BlockBegin)
634             {
635                 BlockBegin = FALSE;
636             }
637             else
638             {
639                 /*
640                  * Backup to previous non-whitespace
641                  */
642                 Beginning = SubBuffer - 1;
643                 while ((*Beginning == ' ')   ||
644                        (*Beginning == '\n'))
645                 {
646                     Beginning--;
647                 }
648 
649                 StartOfThisLine = Beginning;
650                 while (*StartOfThisLine != '\n')
651                 {
652                     StartOfThisLine--;
653                 }
654 
655                 /*
656                  * Move the brace up to the previous line, UNLESS:
657                  *
658                  * 1) There is a conditional compile on the line (starts with '#')
659                  * 2) Previous line ends with an '=' (Start of initializer block)
660                  * 3) Previous line ends with a comma (part of an init list)
661                  * 4) Previous line ends with a backslash (part of a macro)
662                  */
663                 if ((StartOfThisLine[1] != '#') &&
664                     (*Beginning != '\\') &&
665                     (*Beginning != '/') &&
666                     (*Beginning != '{') &&
667                     (*Beginning != '=') &&
668                     (*Beginning != ','))
669                 {
670                     Beginning++;
671                     SubBuffer++;
672                     Length = strlen (SubBuffer);
673 
674                     Gbl_MadeChanges = TRUE;
675 
676 #ifdef ADD_EXTRA_WHITESPACE
677                     AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
678 #else
679                     /* Find non-whitespace start of next line */
680 
681                     Next = SubBuffer + 1;
682                     while ((*Next == ' ')   ||
683                            (*Next == '\t'))
684                     {
685                         Next++;
686                     }
687 
688                     /* Find non-whitespace start of this line */
689 
690                     StartOfThisLine++;
691                     while ((*StartOfThisLine == ' ')   ||
692                            (*StartOfThisLine == '\t'))
693                     {
694                         StartOfThisLine++;
695                     }
696 
697                     /*
698                      * Must be a single-line comment to need more whitespace
699                      * Even then, we don't need more if the previous statement
700                      * is an "else".
701                      */
702                     if ((Next[0] == '/')  &&
703                         (Next[1] == '*')  &&
704                         (Next[2] != '\n') &&
705 
706                         (!strncmp (StartOfThisLine, "else if", 7)     ||
707                          !strncmp (StartOfThisLine, "else while", 10) ||
708                           strncmp (StartOfThisLine, "else", 4)))
709                     {
710                         AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
711                     }
712                     else
713                     {
714                         AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2);
715                     }
716 #endif
717                 }
718             }
719         }
720 
721         SubBuffer++;
722     }
723 }
724 
725 
726 /******************************************************************************
727  *
728  * FUNCTION:    AsTabify4
729  *
730  * DESCRIPTION: Convert the text to tabbed text.  Alignment of text is
731  *              preserved.
732  *
733  ******************************************************************************/
734 
735 void
736 AsTabify4 (
737     char                    *Buffer)
738 {
739     char                    *SubBuffer = Buffer;
740     char                    *NewSubBuffer;
741     UINT32                  SpaceCount = 0;
742     UINT32                  Column = 0;
743 
744 
745     while (*SubBuffer)
746     {
747         if (*SubBuffer == '\n')
748         {
749             Column = 0;
750         }
751         else
752         {
753             Column++;
754         }
755 
756         /* Ignore comments */
757 
758         if ((SubBuffer[0] == '/') &&
759             (SubBuffer[1] == '*'))
760         {
761             SubBuffer = strstr (SubBuffer, "*/");
762             if (!SubBuffer)
763             {
764                 return;
765             }
766 
767             SubBuffer += 2;
768             continue;
769         }
770 
771         /* Ignore quoted strings */
772 
773         if (*SubBuffer == '\"')
774         {
775             SubBuffer++;
776             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
777             if (!SubBuffer)
778             {
779                 return;
780             }
781             SpaceCount = 0;
782         }
783 
784         if (*SubBuffer == ' ')
785         {
786             SpaceCount++;
787 
788             if (SpaceCount >= 4)
789             {
790                 SpaceCount = 0;
791 
792                 NewSubBuffer = (SubBuffer + 1) - 4;
793                 *NewSubBuffer = '\t';
794                 NewSubBuffer++;
795 
796                 /* Remove the spaces */
797 
798                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1);
799             }
800 
801             if ((Column % 4) == 0)
802             {
803                 SpaceCount = 0;
804             }
805         }
806         else
807         {
808             SpaceCount = 0;
809         }
810 
811         SubBuffer++;
812     }
813 }
814 
815 
816 /******************************************************************************
817  *
818  * FUNCTION:    AsTabify8
819  *
820  * DESCRIPTION: Convert the text to tabbed text.  Alignment of text is
821  *              preserved.
822  *
823  ******************************************************************************/
824 
825 void
826 AsTabify8 (
827     char                    *Buffer)
828 {
829     char                    *SubBuffer = Buffer;
830     char                    *NewSubBuffer;
831     char                    *CommentEnd = NULL;
832     UINT32                  SpaceCount = 0;
833     UINT32                  Column = 0;
834     UINT32                  TabCount = 0;
835     UINT32                  LastLineTabCount = 0;
836     UINT32                  LastLineColumnStart = 0;
837     UINT32                  ThisColumnStart = 0;
838     UINT32                  ThisTabCount =  0;
839     char                    *FirstNonBlank = NULL;
840 
841 
842     while (*SubBuffer)
843     {
844         if (*SubBuffer == '\n')
845         {
846             /* This is a standalone blank line */
847 
848             FirstNonBlank = NULL;
849             Column = 0;
850             SpaceCount = 0;
851             TabCount = 0;
852             SubBuffer++;
853             continue;
854         }
855 
856         if (!FirstNonBlank)
857         {
858             /* Find the first non-blank character on this line */
859 
860             FirstNonBlank = SubBuffer;
861             while (*FirstNonBlank == ' ')
862             {
863                 FirstNonBlank++;
864             }
865 
866             /*
867              * This mechanism limits the difference in tab counts from
868              * line to line.  It helps avoid the situation where a second
869              * continuation line (which was indented correctly for tabs=4) would
870              * get indented off the screen if we just blindly converted to tabs.
871              */
872             ThisColumnStart = FirstNonBlank - SubBuffer;
873 
874             if (LastLineTabCount == 0)
875             {
876                 ThisTabCount = 0;
877             }
878             else if (ThisColumnStart == LastLineColumnStart)
879             {
880                 ThisTabCount = LastLineTabCount -1;
881             }
882             else
883             {
884                 ThisTabCount = LastLineTabCount + 1;
885             }
886         }
887 
888         Column++;
889 
890         /* Check if we are in a comment */
891 
892         if ((SubBuffer[0] == '*') &&
893             (SubBuffer[1] == '/'))
894         {
895             SpaceCount = 0;
896             SubBuffer += 2;
897 
898             if (*SubBuffer == '\n')
899             {
900                 if (TabCount > 0)
901                 {
902                     LastLineTabCount = TabCount;
903                     TabCount = 0;
904                 }
905                 FirstNonBlank = NULL;
906                 LastLineColumnStart = ThisColumnStart;
907                 SubBuffer++;
908             }
909 
910             continue;
911         }
912 
913         /* Check for comment open */
914 
915         if ((SubBuffer[0] == '/') &&
916             (SubBuffer[1] == '*'))
917         {
918             /* Find the end of the comment, it must exist */
919 
920             CommentEnd = strstr (SubBuffer, "*/");
921             if (!CommentEnd)
922             {
923                 return;
924             }
925 
926             /* Toss the rest of this line or single-line comment */
927 
928             while ((SubBuffer < CommentEnd) &&
929                    (*SubBuffer != '\n'))
930             {
931                 SubBuffer++;
932             }
933 
934             if (*SubBuffer == '\n')
935             {
936                 if (TabCount > 0)
937                 {
938                     LastLineTabCount = TabCount;
939                     TabCount = 0;
940                 }
941                 FirstNonBlank = NULL;
942                 LastLineColumnStart = ThisColumnStart;
943             }
944 
945             SpaceCount = 0;
946             continue;
947         }
948 
949         /* Ignore quoted strings */
950 
951         if ((!CommentEnd) && (*SubBuffer == '\"'))
952         {
953             SubBuffer++;
954             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
955             if (!SubBuffer)
956             {
957                 return;
958             }
959             SpaceCount = 0;
960         }
961 
962         if (*SubBuffer != ' ')
963         {
964             /* Not a space, skip to end of line */
965 
966             SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
967             if (!SubBuffer)
968             {
969                 return;
970             }
971             if (TabCount > 0)
972             {
973                 LastLineTabCount = TabCount;
974                 TabCount = 0;
975             }
976 
977             FirstNonBlank = NULL;
978             LastLineColumnStart = ThisColumnStart;
979             Column = 0;
980             SpaceCount = 0;
981         }
982         else
983         {
984             /* Another space */
985 
986             SpaceCount++;
987 
988             if (SpaceCount >= 4)
989             {
990                 /* Replace this group of spaces with a tab character */
991 
992                 SpaceCount = 0;
993 
994                 NewSubBuffer = SubBuffer - 3;
995 
996                 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0)
997                 {
998                     *NewSubBuffer = '\t';
999                     NewSubBuffer++;
1000                     SubBuffer++;
1001                     TabCount++;
1002                 }
1003 
1004                 /* Remove the spaces */
1005 
1006                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer);
1007                 continue;
1008             }
1009         }
1010 
1011         SubBuffer++;
1012     }
1013 }
1014 
1015 
1016 /******************************************************************************
1017  *
1018  * FUNCTION:    AsCountLines
1019  *
1020  * DESCRIPTION: Count the number of lines in the input buffer.  Also count
1021  *              the number of long lines (lines longer than 80 chars).
1022  *
1023  ******************************************************************************/
1024 
1025 UINT32
1026 AsCountLines (
1027     char                    *Buffer,
1028     char                    *Filename)
1029 {
1030     char                    *SubBuffer = Buffer;
1031     char                    *EndOfLine;
1032     UINT32                  LineCount = 0;
1033     UINT32                  LongLineCount = 0;
1034 
1035 
1036     while (*SubBuffer)
1037     {
1038         EndOfLine = AsSkipUntilChar (SubBuffer, '\n');
1039         if (!EndOfLine)
1040         {
1041             Gbl_TotalLines += LineCount;
1042             return LineCount;
1043         }
1044 
1045         if ((EndOfLine - SubBuffer) > 80)
1046         {
1047             LongLineCount++;
1048             VERBOSE_PRINT (("long: %.80s\n", SubBuffer));
1049         }
1050 
1051         LineCount++;
1052         SubBuffer = EndOfLine + 1;
1053     }
1054 
1055     if (LongLineCount)
1056     {
1057         VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n", LongLineCount, Filename));
1058         Gbl_LongLines += LongLineCount;
1059     }
1060 
1061     Gbl_TotalLines += LineCount;
1062     return LineCount;
1063 }
1064 
1065 
1066 /******************************************************************************
1067  *
1068  * FUNCTION:    AsCountTabs
1069  *
1070  * DESCRIPTION: Simply count the number of tabs in the input file buffer
1071  *
1072  ******************************************************************************/
1073 
1074 void
1075 AsCountTabs (
1076     char                    *Buffer,
1077     char                    *Filename)
1078 {
1079     UINT32                  i;
1080     UINT32                  TabCount = 0;
1081 
1082 
1083     for (i = 0; Buffer[i]; i++)
1084     {
1085         if (Buffer[i] == '\t')
1086         {
1087             TabCount++;
1088         }
1089     }
1090 
1091     if (TabCount)
1092     {
1093         AsPrint ("Tabs found", TabCount, Filename);
1094         Gbl_Tabs += TabCount;
1095     }
1096 
1097     AsCountLines (Buffer, Filename);
1098 }
1099 
1100 
1101 /******************************************************************************
1102  *
1103  * FUNCTION:    AsCountNonAnsiComments
1104  *
1105  * DESCRIPTION: Count the number of "//" comments.  This type of comment is
1106  *              non-ANSI C.
1107  *
1108  ******************************************************************************/
1109 
1110 void
1111 AsCountNonAnsiComments (
1112     char                    *Buffer,
1113     char                    *Filename)
1114 {
1115     char                    *SubBuffer = Buffer;
1116     UINT32                  CommentCount = 0;
1117 
1118 
1119     while (SubBuffer)
1120     {
1121         SubBuffer = strstr (SubBuffer, "//");
1122         if (SubBuffer)
1123         {
1124             CommentCount++;
1125             SubBuffer += 2;
1126         }
1127     }
1128 
1129     if (CommentCount)
1130     {
1131         AsPrint ("Non-ANSI Comments found", CommentCount, Filename);
1132         Gbl_NonAnsiComments += CommentCount;
1133     }
1134 }
1135 
1136 
1137 /******************************************************************************
1138  *
1139  * FUNCTION:    AsCountSourceLines
1140  *
1141  * DESCRIPTION: Count the number of C source lines.  Defined by 1) not a
1142  *              comment, and 2) not a blank line.
1143  *
1144  ******************************************************************************/
1145 
1146 void
1147 AsCountSourceLines (
1148     char                    *Buffer,
1149     char                    *Filename)
1150 {
1151     char                    *SubBuffer = Buffer;
1152     UINT32                  LineCount = 0;
1153     UINT32                  WhiteCount = 0;
1154     UINT32                  CommentCount = 0;
1155 
1156 
1157     while (*SubBuffer)
1158     {
1159         /* Detect comments (// comments are not used, non-ansii) */
1160 
1161         if ((SubBuffer[0] == '/') &&
1162             (SubBuffer[1] == '*'))
1163         {
1164             SubBuffer += 2;
1165 
1166             /* First line of multi-line comment is often just whitespace */
1167 
1168             if (SubBuffer[0] == '\n')
1169             {
1170                 WhiteCount++;
1171                 SubBuffer++;
1172             }
1173             else
1174             {
1175                 CommentCount++;
1176             }
1177 
1178             /* Find end of comment */
1179 
1180             while (SubBuffer[0] && SubBuffer[1] &&
1181                     !(((SubBuffer[0] == '*') &&
1182                       (SubBuffer[1] == '/'))))
1183             {
1184                 if (SubBuffer[0] == '\n')
1185                 {
1186                     CommentCount++;
1187                 }
1188 
1189                 SubBuffer++;
1190             }
1191         }
1192 
1193         /* A linefeed followed by a non-linefeed is a valid source line */
1194 
1195         else if ((SubBuffer[0] == '\n') &&
1196                  (SubBuffer[1] != '\n'))
1197         {
1198             LineCount++;
1199         }
1200 
1201         /* Two back-to-back linefeeds indicate a whitespace line */
1202 
1203         else if ((SubBuffer[0] == '\n') &&
1204                  (SubBuffer[1] == '\n'))
1205         {
1206             WhiteCount++;
1207         }
1208 
1209         SubBuffer++;
1210     }
1211 
1212     /* Adjust comment count for legal header */
1213 
1214     if (Gbl_HeaderSize < CommentCount)
1215     {
1216         CommentCount -= Gbl_HeaderSize;
1217         Gbl_HeaderLines += Gbl_HeaderSize;
1218     }
1219 
1220     Gbl_SourceLines += LineCount;
1221     Gbl_WhiteLines += WhiteCount;
1222     Gbl_CommentLines += CommentCount;
1223 
1224     VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n",
1225                 CommentCount, WhiteCount, LineCount, LineCount+WhiteCount+CommentCount, Filename));
1226 }
1227 
1228 
1229 /******************************************************************************
1230  *
1231  * FUNCTION:    AsInsertPrefix
1232  *
1233  * DESCRIPTION: Insert struct or union prefixes
1234  *
1235  ******************************************************************************/
1236 
1237 void
1238 AsInsertPrefix (
1239     char                    *Buffer,
1240     char                    *Keyword,
1241     UINT8                   Type)
1242 {
1243     char                    *SubString;
1244     char                    *SubBuffer;
1245     char                    *EndKeyword;
1246     int                     StrLength;
1247     int                     InsertLength;
1248     char                    *InsertString;
1249     int                     TrailingSpaces;
1250     char                    LowerKeyword[128];
1251     int                     KeywordLength;
1252 
1253 
1254     switch (Type)
1255     {
1256     case SRC_TYPE_STRUCT:
1257         InsertString = "struct ";
1258         break;
1259 
1260     case SRC_TYPE_UNION:
1261         InsertString = "union ";
1262         break;
1263 
1264     default:
1265         return;
1266     }
1267 
1268     strcpy (LowerKeyword, Keyword);
1269     strlwr (LowerKeyword);
1270 
1271     SubBuffer = Buffer;
1272     SubString = Buffer;
1273     InsertLength = strlen (InsertString);
1274     KeywordLength = strlen (Keyword);
1275 
1276 
1277     while (SubString)
1278     {
1279         /* Find an instance of the keyword */
1280 
1281         SubString = strstr (SubBuffer, LowerKeyword);
1282 
1283         if (!SubString)
1284         {
1285             return;
1286         }
1287 
1288         SubBuffer = SubString;
1289 
1290         /* Must be standalone word, not a substring */
1291 
1292         if (AsMatchExactWord (SubString, KeywordLength))
1293         {
1294             /* Make sure the keyword isn't already prefixed with the insert */
1295 
1296             if (!strncmp (SubString - InsertLength, InsertString, InsertLength))
1297             {
1298                 /* Add spaces if not already at the end-of-line */
1299 
1300                 if (*(SubBuffer + KeywordLength) != '\n')
1301                 {
1302                     /* Already present, add spaces after to align structure members */
1303 
1304 #if 0
1305 /* ONLY FOR C FILES */
1306                     AsInsertData (SubBuffer + KeywordLength, "        ", 8);
1307 #endif
1308                 }
1309                 goto Next;
1310             }
1311 
1312             /* Make sure the keyword isn't at the end of a struct/union */
1313             /* Note: This code depends on a single space after the brace */
1314 
1315             if (*(SubString - 2) == '}')
1316             {
1317                 goto Next;
1318             }
1319 
1320             /* Prefix the keyword with the insert string */
1321 
1322             Gbl_MadeChanges = TRUE;
1323             StrLength = strlen (SubString);
1324 
1325             /* Is there room for insertion */
1326 
1327             EndKeyword = SubString + strlen (LowerKeyword);
1328 
1329             TrailingSpaces = 0;
1330             while (EndKeyword[TrailingSpaces] == ' ')
1331             {
1332                 TrailingSpaces++;
1333             }
1334 
1335             /*
1336              * Use "if (TrailingSpaces > 1)" if we want to ignore casts
1337              */
1338             SubBuffer = SubString + InsertLength;
1339 
1340             if (TrailingSpaces > InsertLength)
1341             {
1342                 /* Insert the keyword */
1343 
1344                 memmove (SubBuffer, SubString, KeywordLength);
1345 
1346                 /* Insert the keyword */
1347 
1348                 memmove (SubString, InsertString, InsertLength);
1349             }
1350             else
1351             {
1352                 AsInsertData (SubString, InsertString, InsertLength);
1353             }
1354         }
1355 
1356 Next:
1357         SubBuffer += KeywordLength;
1358     }
1359 }
1360 
1361 #ifdef ACPI_FUTURE_IMPLEMENTATION
1362 /******************************************************************************
1363  *
1364  * FUNCTION:    AsTrimComments
1365  *
1366  * DESCRIPTION: Finds 3-line comments with only a single line of text
1367  *
1368  ******************************************************************************/
1369 
1370 void
1371 AsTrimComments (
1372     char                    *Buffer,
1373     char                    *Filename)
1374 {
1375     char                    *SubBuffer = Buffer;
1376     char                    *Ptr1;
1377     char                    *Ptr2;
1378     UINT32                  LineCount;
1379     UINT32                  ShortCommentCount = 0;
1380 
1381 
1382     while (1)
1383     {
1384         /* Find comment open, within procedure level */
1385 
1386         SubBuffer = strstr (SubBuffer, "    /*");
1387         if (!SubBuffer)
1388         {
1389             goto Exit;
1390         }
1391 
1392         /* Find comment terminator */
1393 
1394         Ptr1 = strstr (SubBuffer, "*/");
1395         if (!Ptr1)
1396         {
1397             goto Exit;
1398         }
1399 
1400         /* Find next EOL (from original buffer) */
1401 
1402         Ptr2 = strstr (SubBuffer, "\n");
1403         if (!Ptr2)
1404         {
1405             goto Exit;
1406         }
1407 
1408         /* Ignore one-line comments */
1409 
1410         if (Ptr1 < Ptr2)
1411         {
1412             /* Normal comment, ignore and continue; */
1413 
1414             SubBuffer = Ptr2;
1415             continue;
1416         }
1417 
1418         /* Examine multi-line comment */
1419 
1420         LineCount = 1;
1421         while (Ptr1 > Ptr2)
1422         {
1423             /* Find next EOL */
1424 
1425             Ptr2++;
1426             Ptr2 = strstr (Ptr2, "\n");
1427             if (!Ptr2)
1428             {
1429                 goto Exit;
1430             }
1431 
1432             LineCount++;
1433         }
1434 
1435         SubBuffer = Ptr1;
1436 
1437         if (LineCount <= 3)
1438         {
1439             ShortCommentCount++;
1440         }
1441     }
1442 
1443 
1444 Exit:
1445 
1446     if (ShortCommentCount)
1447     {
1448         AsPrint ("Short Comments found", ShortCommentCount, Filename);
1449     }
1450 }
1451 #endif
1452 
1453 
1454