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