Merge branch 'vendor/OPENSSL'
[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/else 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     UINT32                  TotalLines = 1;
284     char                    *EndBuffer;
285
286
287     EndBuffer = SubBuffer + strlen (SubBuffer);
288
289     while (SubBuffer <= EndBuffer)
290     {
291         /* TBD: Update this function to work properly, as per code below */
292         /* SubBuffer = AsCheckAndSkipLiterals (SubBuffer, &TotalLines); */
293
294         /* Skip normal comments */
295
296         if ((*SubBuffer == '/') &&
297             (*(SubBuffer + 1) == '*'))
298         {
299             /* Must maintain line count */
300
301             SubBuffer += 2;
302             while (strncmp ("*/", SubBuffer, 2))
303             {
304                 if (*SubBuffer == '\n')
305                 {
306                     TotalLines++;
307                 }
308                 SubBuffer++;
309             }
310             SubBuffer += 2;
311             continue;
312         }
313
314         /* Skip single quoted chars */
315
316         if (*SubBuffer == '\'')
317         {
318             SubBuffer++;
319             if (*SubBuffer == '\\')
320             {
321                 SubBuffer++;
322             }
323             SubBuffer++;
324             continue;
325         }
326
327         /* Skip quoted strings */
328
329         if (*SubBuffer == '"')
330         {
331             SubBuffer++;
332             while (*SubBuffer != '"')
333             {
334                 /* Handle escapes within the string */
335
336                 if (*SubBuffer == '\\')
337                 {
338                     SubBuffer++;
339                 }
340                 SubBuffer++;
341             }
342
343             SubBuffer++;
344             continue;
345         }
346
347         if (*SubBuffer == '\n')
348         {
349             TotalLines++;
350         }
351         else if (!(strncmp (" if", SubBuffer, 3)))
352         {
353             SubBuffer += 2;
354
355             NextBrace = strstr (SubBuffer, "{");
356             NextSemicolon = strstr (SubBuffer, ";");
357
358             if ((!NextBrace) ||
359                (NextSemicolon && (NextBrace > NextSemicolon)))
360             {
361                 Gbl_MissingBraces++;
362
363                 if (!Gbl_QuietMode)
364                 {
365                     printf ("Missing braces for <if>, line %u: %s\n", TotalLines, Filename);
366                 }
367             }
368         }
369         else if (!(strncmp (" else if", SubBuffer, 8)))
370         {
371             SubBuffer += 7;
372
373             NextBrace = strstr (SubBuffer, "{");
374             NextSemicolon = strstr (SubBuffer, ";");
375
376             if ((!NextBrace) ||
377                (NextSemicolon && (NextBrace > NextSemicolon)))
378             {
379                 Gbl_MissingBraces++;
380
381                 if (!Gbl_QuietMode)
382                 {
383                     printf ("Missing braces for <else if>, line %u: %s\n", TotalLines, Filename);
384                 }
385             }
386         }
387         else if (!(strncmp (" else", SubBuffer, 5)))
388         {
389             SubBuffer += 4;
390             NextBrace = strstr (SubBuffer, "{");
391             NextSemicolon = strstr (SubBuffer, ";");
392
393             if ((!NextBrace) ||
394                (NextSemicolon && (NextBrace > NextSemicolon)))
395             {
396                 Gbl_MissingBraces++;
397
398                 if (!Gbl_QuietMode)
399                 {
400                     printf ("Missing braces for <else>, line %u: %s\n", TotalLines, Filename);
401                 }
402             }
403         }
404
405         SubBuffer++;
406     }
407 }
408
409
410 /******************************************************************************
411  *
412  * FUNCTION:    AsTrimLines
413  *
414  * DESCRIPTION: Remove extra blanks from the end of source lines. Does not
415  *              check for tabs.
416  *
417  ******************************************************************************/
418
419 void
420 AsTrimLines (
421     char                    *Buffer,
422     char                    *Filename)
423 {
424     char                    *SubBuffer = Buffer;
425     char                    *StartWhiteSpace = NULL;
426     UINT32                  SpaceCount = 0;
427
428
429     while (*SubBuffer)
430     {
431         while (*SubBuffer != '\n')
432         {
433             if (!*SubBuffer)
434             {
435                 goto Exit;
436             }
437
438             if (*SubBuffer == ' ')
439             {
440                 if (!StartWhiteSpace)
441                 {
442                     StartWhiteSpace = SubBuffer;
443                 }
444             }
445             else
446             {
447                 StartWhiteSpace = NULL;
448             }
449
450             SubBuffer++;
451         }
452
453         if (StartWhiteSpace)
454         {
455             SpaceCount += (SubBuffer - StartWhiteSpace);
456
457             /* Remove the spaces */
458
459             SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer);
460             StartWhiteSpace = NULL;
461         }
462
463         SubBuffer++;
464     }
465
466
467 Exit:
468     if (SpaceCount)
469     {
470         Gbl_MadeChanges = TRUE;
471         AsPrint ("Extraneous spaces removed", SpaceCount, Filename);
472     }
473 }
474
475
476 /******************************************************************************
477  *
478  * FUNCTION:    AsTrimWhitespace
479  *
480  * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines.
481  *              this can happen during the translation when lines are removed.
482  *
483  ******************************************************************************/
484
485 void
486 AsTrimWhitespace (
487     char                    *Buffer)
488 {
489     int                     ReplaceCount = 1;
490
491
492     while (ReplaceCount)
493     {
494         ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", REPLACE_SUBSTRINGS, Buffer);
495     }
496 }
497
498
499 /******************************************************************************
500  *
501  * FUNCTION:    AsReplaceHeader
502  *
503  * DESCRIPTION: Replace the default Intel legal header with a new header
504  *
505  ******************************************************************************/
506
507 void
508 AsReplaceHeader (
509     char                    *Buffer,
510     char                    *NewHeader)
511 {
512     char                    *SubBuffer;
513     char                    *TokenEnd;
514
515
516     /* Find the original header */
517
518     SubBuffer = strstr (Buffer, HeaderBegin);
519     if (!SubBuffer)
520     {
521         return;
522     }
523
524     /* Find the end of the original header */
525
526     TokenEnd = strstr (SubBuffer, "*/");
527     TokenEnd = AsSkipPastChar (TokenEnd, '\n');
528
529     /* Delete old header, insert new one */
530
531     AsReplaceData (SubBuffer, TokenEnd - SubBuffer, NewHeader, strlen (NewHeader));
532 }
533
534
535 /******************************************************************************
536  *
537  * FUNCTION:    AsReplaceString
538  *
539  * DESCRIPTION: Replace all instances of a target string with a replacement
540  *              string. Returns count of the strings replaced.
541  *
542  ******************************************************************************/
543
544 int
545 AsReplaceString (
546     char                    *Target,
547     char                    *Replacement,
548     UINT8                   Type,
549     char                    *Buffer)
550 {
551     char                    *SubString1;
552     char                    *SubString2;
553     char                    *SubBuffer;
554     int                     TargetLength;
555     int                     ReplacementLength;
556     int                     ReplaceCount = 0;
557
558
559     TargetLength = strlen (Target);
560     ReplacementLength = strlen (Replacement);
561
562     SubBuffer = Buffer;
563     SubString1 = Buffer;
564
565     while (SubString1)
566     {
567         /* Find the target string */
568
569         SubString1 = strstr (SubBuffer, Target);
570         if (!SubString1)
571         {
572             return (ReplaceCount);
573         }
574
575         /*
576          * Check for translation escape string -- means to ignore
577          * blocks of code while replacing
578          */
579         if (Gbl_IgnoreTranslationEscapes)
580         {
581             SubString2 = NULL;
582         }
583         else
584         {
585             SubString2 = strstr (SubBuffer, AS_START_IGNORE);
586         }
587
588         if ((SubString2) &&
589             (SubString2 < SubString1))
590         {
591             /* Find end of the escape block starting at "Substring2" */
592
593             SubString2 = strstr (SubString2, AS_STOP_IGNORE);
594             if (!SubString2)
595             {
596                 /* Didn't find terminator */
597
598                 return (ReplaceCount);
599             }
600
601             /* Move buffer to end of escape block and continue */
602
603             SubBuffer = SubString2;
604         }
605
606         /* Do the actual replace if the target was found */
607
608         else
609         {
610             if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD)
611             {
612                 if (!AsMatchExactWord (SubString1, TargetLength))
613                 {
614                     SubBuffer = SubString1 + 1;
615                     continue;
616                 }
617             }
618
619             SubBuffer = AsReplaceData (SubString1, TargetLength, Replacement, ReplacementLength);
620
621             if ((Type & EXTRA_INDENT_C) &&
622                 (!Gbl_StructDefs))
623             {
624                 SubBuffer = AsInsertData (SubBuffer, "        ", 8);
625             }
626
627             ReplaceCount++;
628         }
629     }
630
631     return (ReplaceCount);
632 }
633
634
635 /******************************************************************************
636  *
637  * FUNCTION:    AsConvertToLineFeeds
638  *
639  * DESCRIPTION:
640  *
641  ******************************************************************************/
642
643 void
644 AsConvertToLineFeeds (
645     char                    *Buffer)
646 {
647     char                    *SubString;
648     char                    *SubBuffer;
649
650
651     SubBuffer = Buffer;
652     SubString = Buffer;
653
654     while (SubString)
655     {
656         /* Find the target string */
657
658         SubString = strstr (SubBuffer, "\r\n");
659         if (!SubString)
660         {
661             return;
662         }
663
664         SubBuffer = AsReplaceData (SubString, 1, NULL, 0);
665     }
666     return;
667 }
668
669
670 /******************************************************************************
671  *
672  * FUNCTION:    AsInsertCarriageReturns
673  *
674  * DESCRIPTION:
675  *
676  ******************************************************************************/
677
678 void
679 AsInsertCarriageReturns (
680     char                    *Buffer)
681 {
682     char                    *SubString;
683     char                    *SubBuffer;
684
685
686     SubBuffer = Buffer;
687     SubString = Buffer;
688
689     while (SubString)
690     {
691         /* Find the target string */
692
693         SubString = strstr (SubBuffer, "\n");
694         if (!SubString)
695         {
696             return;
697         }
698
699         SubBuffer = AsInsertData (SubString, "\r", 1);
700         SubBuffer += 1;
701     }
702     return;
703 }
704
705
706 /******************************************************************************
707  *
708  * FUNCTION:    AsBracesOnSameLine
709  *
710  * DESCRIPTION: Move opening braces up to the same line as an if, for, else,
711  *              or while statement (leave function opening brace on separate
712  *              line).
713  *
714  ******************************************************************************/
715
716 void
717 AsBracesOnSameLine (
718     char                    *Buffer)
719 {
720     char                    *SubBuffer = Buffer;
721     char                    *Beginning;
722     char                    *StartOfThisLine;
723     char                    *Next;
724     BOOLEAN                 BlockBegin = TRUE;
725
726
727     while (*SubBuffer)
728     {
729         /* Ignore comments */
730
731         if ((SubBuffer[0] == '/') &&
732             (SubBuffer[1] == '*'))
733         {
734             SubBuffer = strstr (SubBuffer, "*/");
735             if (!SubBuffer)
736             {
737                 return;
738             }
739
740             SubBuffer += 2;
741             continue;
742         }
743
744         /* Ignore quoted strings */
745
746         if (*SubBuffer == '\"')
747         {
748             SubBuffer++;
749             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
750             if (!SubBuffer)
751             {
752                 return;
753             }
754         }
755
756         if (!strncmp ("\n}", SubBuffer, 2))
757         {
758             /*
759              * A newline followed by a closing brace closes a function
760              * or struct or initializer block
761              */
762             BlockBegin = TRUE;
763         }
764
765         /*
766          * Move every standalone brace up to the previous line
767          * Check for digit will ignore initializer lists surrounded by braces.
768          * This will work until we we need more complex detection.
769          */
770         if ((*SubBuffer == '{') && !isdigit ((int) SubBuffer[1]))
771         {
772             if (BlockBegin)
773             {
774                 BlockBegin = FALSE;
775             }
776             else
777             {
778                 /*
779                  * Backup to previous non-whitespace
780                  */
781                 Beginning = SubBuffer - 1;
782                 while ((*Beginning == ' ')   ||
783                        (*Beginning == '\n'))
784                 {
785                     Beginning--;
786                 }
787
788                 StartOfThisLine = Beginning;
789                 while (*StartOfThisLine != '\n')
790                 {
791                     StartOfThisLine--;
792                 }
793
794                 /*
795                  * Move the brace up to the previous line, UNLESS:
796                  *
797                  * 1) There is a conditional compile on the line (starts with '#')
798                  * 2) Previous line ends with an '=' (Start of initializer block)
799                  * 3) Previous line ends with a comma (part of an init list)
800                  * 4) Previous line ends with a backslash (part of a macro)
801                  */
802                 if ((StartOfThisLine[1] != '#') &&
803                     (*Beginning != '\\') &&
804                     (*Beginning != '/') &&
805                     (*Beginning != '{') &&
806                     (*Beginning != '=') &&
807                     (*Beginning != ','))
808                 {
809                     Beginning++;
810                     SubBuffer++;
811
812                     Gbl_MadeChanges = TRUE;
813
814 #ifdef ADD_EXTRA_WHITESPACE
815                     AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
816 #else
817                     /* Find non-whitespace start of next line */
818
819                     Next = SubBuffer + 1;
820                     while ((*Next == ' ')   ||
821                            (*Next == '\t'))
822                     {
823                         Next++;
824                     }
825
826                     /* Find non-whitespace start of this line */
827
828                     StartOfThisLine++;
829                     while ((*StartOfThisLine == ' ')   ||
830                            (*StartOfThisLine == '\t'))
831                     {
832                         StartOfThisLine++;
833                     }
834
835                     /*
836                      * Must be a single-line comment to need more whitespace
837                      * Even then, we don't need more if the previous statement
838                      * is an "else".
839                      */
840                     if ((Next[0] == '/')  &&
841                         (Next[1] == '*')  &&
842                         (Next[2] != '\n') &&
843
844                         (!strncmp (StartOfThisLine, "else if", 7)     ||
845                          !strncmp (StartOfThisLine, "else while", 10) ||
846                           strncmp (StartOfThisLine, "else", 4)))
847                     {
848                         AsReplaceData (Beginning, SubBuffer - Beginning, " {\n", 3);
849                     }
850                     else
851                     {
852                         AsReplaceData (Beginning, SubBuffer - Beginning, " {", 2);
853                     }
854 #endif
855                 }
856             }
857         }
858
859         SubBuffer++;
860     }
861 }
862
863
864 /******************************************************************************
865  *
866  * FUNCTION:    AsTabify4
867  *
868  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
869  *              preserved.
870  *
871  ******************************************************************************/
872
873 void
874 AsTabify4 (
875     char                    *Buffer)
876 {
877     char                    *SubBuffer = Buffer;
878     char                    *NewSubBuffer;
879     UINT32                  SpaceCount = 0;
880     UINT32                  Column = 0;
881
882
883     while (*SubBuffer)
884     {
885         if (*SubBuffer == '\n')
886         {
887             Column = 0;
888         }
889         else
890         {
891             Column++;
892         }
893
894         /* Ignore comments */
895
896         if ((SubBuffer[0] == '/') &&
897             (SubBuffer[1] == '*'))
898         {
899             SubBuffer = strstr (SubBuffer, "*/");
900             if (!SubBuffer)
901             {
902                 return;
903             }
904
905             SubBuffer += 2;
906             continue;
907         }
908
909         /* Ignore quoted strings */
910
911         if (*SubBuffer == '\"')
912         {
913             SubBuffer++;
914             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
915             if (!SubBuffer)
916             {
917                 return;
918             }
919             SpaceCount = 0;
920         }
921
922         if (*SubBuffer == ' ')
923         {
924             SpaceCount++;
925
926             if (SpaceCount >= 4)
927             {
928                 SpaceCount = 0;
929
930                 NewSubBuffer = (SubBuffer + 1) - 4;
931                 *NewSubBuffer = '\t';
932                 NewSubBuffer++;
933
934                 /* Remove the spaces */
935
936                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1);
937             }
938
939             if ((Column % 4) == 0)
940             {
941                 SpaceCount = 0;
942             }
943         }
944         else
945         {
946             SpaceCount = 0;
947         }
948
949         SubBuffer++;
950     }
951 }
952
953
954 /******************************************************************************
955  *
956  * FUNCTION:    AsTabify8
957  *
958  * DESCRIPTION: Convert the text to tabbed text. Alignment of text is
959  *              preserved.
960  *
961  ******************************************************************************/
962
963 void
964 AsTabify8 (
965     char                    *Buffer)
966 {
967     char                    *SubBuffer = Buffer;
968     char                    *NewSubBuffer;
969     char                    *CommentEnd = NULL;
970     UINT32                  SpaceCount = 0;
971     UINT32                  Column = 0;
972     UINT32                  TabCount = 0;
973     UINT32                  LastLineTabCount = 0;
974     UINT32                  LastLineColumnStart = 0;
975     UINT32                  ThisColumnStart = 0;
976     UINT32                  ThisTabCount =  0;
977     char                    *FirstNonBlank = NULL;
978
979
980     while (*SubBuffer)
981     {
982         if (*SubBuffer == '\n')
983         {
984             /* This is a standalone blank line */
985
986             FirstNonBlank = NULL;
987             Column = 0;
988             SpaceCount = 0;
989             TabCount = 0;
990             SubBuffer++;
991             continue;
992         }
993
994         if (!FirstNonBlank)
995         {
996             /* Find the first non-blank character on this line */
997
998             FirstNonBlank = SubBuffer;
999             while (*FirstNonBlank == ' ')
1000             {
1001                 FirstNonBlank++;
1002             }
1003
1004             /*
1005              * This mechanism limits the difference in tab counts from
1006              * line to line. It helps avoid the situation where a second
1007              * continuation line (which was indented correctly for tabs=4) would
1008              * get indented off the screen if we just blindly converted to tabs.
1009              */
1010             ThisColumnStart = FirstNonBlank - SubBuffer;
1011
1012             if (LastLineTabCount == 0)
1013             {
1014                 ThisTabCount = 0;
1015             }
1016             else if (ThisColumnStart == LastLineColumnStart)
1017             {
1018                 ThisTabCount = LastLineTabCount -1;
1019             }
1020             else
1021             {
1022                 ThisTabCount = LastLineTabCount + 1;
1023             }
1024         }
1025
1026         Column++;
1027
1028         /* Check if we are in a comment */
1029
1030         if ((SubBuffer[0] == '*') &&
1031             (SubBuffer[1] == '/'))
1032         {
1033             SpaceCount = 0;
1034             SubBuffer += 2;
1035
1036             if (*SubBuffer == '\n')
1037             {
1038                 if (TabCount > 0)
1039                 {
1040                     LastLineTabCount = TabCount;
1041                     TabCount = 0;
1042                 }
1043                 FirstNonBlank = NULL;
1044                 LastLineColumnStart = ThisColumnStart;
1045                 SubBuffer++;
1046             }
1047
1048             continue;
1049         }
1050
1051         /* Check for comment open */
1052
1053         if ((SubBuffer[0] == '/') &&
1054             (SubBuffer[1] == '*'))
1055         {
1056             /* Find the end of the comment, it must exist */
1057
1058             CommentEnd = strstr (SubBuffer, "*/");
1059             if (!CommentEnd)
1060             {
1061                 return;
1062             }
1063
1064             /* Toss the rest of this line or single-line comment */
1065
1066             while ((SubBuffer < CommentEnd) &&
1067                    (*SubBuffer != '\n'))
1068             {
1069                 SubBuffer++;
1070             }
1071
1072             if (*SubBuffer == '\n')
1073             {
1074                 if (TabCount > 0)
1075                 {
1076                     LastLineTabCount = TabCount;
1077                     TabCount = 0;
1078                 }
1079                 FirstNonBlank = NULL;
1080                 LastLineColumnStart = ThisColumnStart;
1081             }
1082
1083             SpaceCount = 0;
1084             continue;
1085         }
1086
1087         /* Ignore quoted strings */
1088
1089         if ((!CommentEnd) && (*SubBuffer == '\"'))
1090         {
1091             SubBuffer++;
1092             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
1093             if (!SubBuffer)
1094             {
1095                 return;
1096             }
1097             SpaceCount = 0;
1098         }
1099
1100         if (*SubBuffer != ' ')
1101         {
1102             /* Not a space, skip to end of line */
1103
1104             SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
1105             if (!SubBuffer)
1106             {
1107                 return;
1108             }
1109             if (TabCount > 0)
1110             {
1111                 LastLineTabCount = TabCount;
1112                 TabCount = 0;
1113             }
1114
1115             FirstNonBlank = NULL;
1116             LastLineColumnStart = ThisColumnStart;
1117             Column = 0;
1118             SpaceCount = 0;
1119         }
1120         else
1121         {
1122             /* Another space */
1123
1124             SpaceCount++;
1125
1126             if (SpaceCount >= 4)
1127             {
1128                 /* Replace this group of spaces with a tab character */
1129
1130                 SpaceCount = 0;
1131
1132                 NewSubBuffer = SubBuffer - 3;
1133
1134                 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0)
1135                 {
1136                     *NewSubBuffer = '\t';
1137                     NewSubBuffer++;
1138                     SubBuffer++;
1139                     TabCount++;
1140                 }
1141
1142                 /* Remove the spaces */
1143
1144                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer);
1145                 continue;
1146             }
1147         }
1148
1149         SubBuffer++;
1150     }
1151 }
1152
1153
1154 /******************************************************************************
1155  *
1156  * FUNCTION:    AsCountLines
1157  *
1158  * DESCRIPTION: Count the number of lines in the input buffer. Also count
1159  *              the number of long lines (lines longer than 80 chars).
1160  *
1161  ******************************************************************************/
1162
1163 UINT32
1164 AsCountLines (
1165     char                    *Buffer,
1166     char                    *Filename)
1167 {
1168     char                    *SubBuffer = Buffer;
1169     char                    *EndOfLine;
1170     UINT32                  LineCount = 0;
1171     UINT32                  LongLineCount = 0;
1172
1173
1174     while (*SubBuffer)
1175     {
1176         EndOfLine = AsSkipUntilChar (SubBuffer, '\n');
1177         if (!EndOfLine)
1178         {
1179             Gbl_TotalLines += LineCount;
1180             return (LineCount);
1181         }
1182
1183         if ((EndOfLine - SubBuffer) > 80)
1184         {
1185             LongLineCount++;
1186             VERBOSE_PRINT (("long: %.80s\n", SubBuffer));
1187         }
1188
1189         LineCount++;
1190         SubBuffer = EndOfLine + 1;
1191     }
1192
1193     if (LongLineCount)
1194     {
1195         VERBOSE_PRINT (("%u Lines longer than 80 found in %s\n", LongLineCount, Filename));
1196         Gbl_LongLines += LongLineCount;
1197     }
1198
1199     Gbl_TotalLines += LineCount;
1200     return (LineCount);
1201 }
1202
1203
1204 /******************************************************************************
1205  *
1206  * FUNCTION:    AsCountTabs
1207  *
1208  * DESCRIPTION: Simply count the number of tabs in the input file buffer
1209  *
1210  ******************************************************************************/
1211
1212 void
1213 AsCountTabs (
1214     char                    *Buffer,
1215     char                    *Filename)
1216 {
1217     UINT32                  i;
1218     UINT32                  TabCount = 0;
1219
1220
1221     for (i = 0; Buffer[i]; i++)
1222     {
1223         if (Buffer[i] == '\t')
1224         {
1225             TabCount++;
1226         }
1227     }
1228
1229     if (TabCount)
1230     {
1231         AsPrint ("Tabs found", TabCount, Filename);
1232         Gbl_Tabs += TabCount;
1233     }
1234
1235     AsCountLines (Buffer, Filename);
1236 }
1237
1238
1239 /******************************************************************************
1240  *
1241  * FUNCTION:    AsCountNonAnsiComments
1242  *
1243  * DESCRIPTION: Count the number of "//" comments. This type of comment is
1244  *              non-ANSI C.
1245  *
1246  * NOTE: July 2014: Allows // within quoted strings and within normal
1247  *       comments. Eliminates extraneous warnings from this utility.
1248  *
1249  ******************************************************************************/
1250
1251 void
1252 AsCountNonAnsiComments (
1253     char                    *Buffer,
1254     char                    *Filename)
1255 {
1256     char                    *SubBuffer = Buffer;
1257     char                    *EndBuffer;
1258     UINT32                  CommentCount = 0;
1259     char                    *StartBuffer;
1260
1261
1262     EndBuffer = SubBuffer + strlen (SubBuffer);
1263
1264     while (SubBuffer <= EndBuffer)
1265     {
1266         /* Skip normal comments */
1267
1268         if ((*SubBuffer == '/') &&
1269             (*(SubBuffer + 1) == '*'))
1270         {
1271             SubBuffer = strstr (SubBuffer + 2, "*/");
1272             if (!SubBuffer)
1273             {
1274                 break;
1275             }
1276
1277             SubBuffer += 2;
1278             continue;
1279         }
1280
1281         /* Skip single quoted chars */
1282
1283         if (*SubBuffer == '\'')
1284         {
1285             SubBuffer++;
1286             if (*SubBuffer == '\\')
1287             {
1288                 SubBuffer++;
1289             }
1290             SubBuffer++;
1291             continue;
1292         }
1293
1294         /* Skip quoted strings */
1295
1296         if (*SubBuffer == '"')
1297         {
1298  StartBuffer = SubBuffer;
1299 AcpiOsPrintf ("START STRING: %.64s\n", StartBuffer);
1300            SubBuffer++;
1301             while (*SubBuffer != '"')
1302             {
1303                 /* Handle escapes within the string */
1304
1305                 if (*SubBuffer == '\\')
1306                 {
1307                     SubBuffer++;
1308                 }
1309                 SubBuffer++;
1310             }
1311
1312             SubBuffer++;
1313             continue;
1314         }
1315
1316         /* Finally: check for slash-slash comment */
1317
1318         if ((*SubBuffer == '/') &&
1319             (*(SubBuffer + 1) == '/'))
1320         {
1321             CommentCount++;
1322             SubBuffer++;
1323         }
1324
1325         SubBuffer++;
1326     }
1327
1328     /* Error if any slash-slash comments found */
1329
1330     if (CommentCount)
1331     {
1332         AsPrint ("Non-ANSI // Comments Found", CommentCount, Filename);
1333         Gbl_NonAnsiComments += CommentCount;
1334     }
1335 }
1336
1337
1338 /******************************************************************************
1339  *
1340  * FUNCTION:    AsCountSourceLines
1341  *
1342  * DESCRIPTION: Count the number of C source lines. Defined by 1) not a
1343  *              comment, and 2) not a blank line.
1344  *
1345  ******************************************************************************/
1346
1347 void
1348 AsCountSourceLines (
1349     char                    *Buffer,
1350     char                    *Filename)
1351 {
1352     char                    *SubBuffer = Buffer;
1353     UINT32                  LineCount = 0;
1354     UINT32                  WhiteCount = 0;
1355     UINT32                  CommentCount = 0;
1356
1357
1358     while (*SubBuffer)
1359     {
1360         /* Detect comments (// comments are not used, non-ansii) */
1361
1362         if ((SubBuffer[0] == '/') &&
1363             (SubBuffer[1] == '*'))
1364         {
1365             SubBuffer += 2;
1366
1367             /* First line of multi-line comment is often just whitespace */
1368
1369             if (SubBuffer[0] == '\n')
1370             {
1371                 WhiteCount++;
1372                 SubBuffer++;
1373             }
1374             else
1375             {
1376                 CommentCount++;
1377             }
1378
1379             /* Find end of comment */
1380
1381             while (SubBuffer[0] && SubBuffer[1] &&
1382                     !(((SubBuffer[0] == '*') &&
1383                       (SubBuffer[1] == '/'))))
1384             {
1385                 if (SubBuffer[0] == '\n')
1386                 {
1387                     CommentCount++;
1388                 }
1389
1390                 SubBuffer++;
1391             }
1392         }
1393
1394         /* A linefeed followed by a non-linefeed is a valid source line */
1395
1396         else if ((SubBuffer[0] == '\n') &&
1397                  (SubBuffer[1] != '\n'))
1398         {
1399             LineCount++;
1400         }
1401
1402         /* Two back-to-back linefeeds indicate a whitespace line */
1403
1404         else if ((SubBuffer[0] == '\n') &&
1405                  (SubBuffer[1] == '\n'))
1406         {
1407             WhiteCount++;
1408         }
1409
1410         SubBuffer++;
1411     }
1412
1413     /* Adjust comment count for legal header */
1414
1415     if (Gbl_HeaderSize < CommentCount)
1416     {
1417         CommentCount -= Gbl_HeaderSize;
1418         Gbl_HeaderLines += Gbl_HeaderSize;
1419     }
1420
1421     Gbl_SourceLines += LineCount;
1422     Gbl_WhiteLines += WhiteCount;
1423     Gbl_CommentLines += CommentCount;
1424
1425     VERBOSE_PRINT (("%u Comment %u White %u Code %u Lines in %s\n",
1426                 CommentCount, WhiteCount, LineCount, LineCount+WhiteCount+CommentCount, Filename));
1427 }
1428
1429
1430 /******************************************************************************
1431  *
1432  * FUNCTION:    AsInsertPrefix
1433  *
1434  * DESCRIPTION: Insert struct or union prefixes
1435  *
1436  ******************************************************************************/
1437
1438 void
1439 AsInsertPrefix (
1440     char                    *Buffer,
1441     char                    *Keyword,
1442     UINT8                   Type)
1443 {
1444     char                    *SubString;
1445     char                    *SubBuffer;
1446     char                    *EndKeyword;
1447     int                     InsertLength;
1448     char                    *InsertString;
1449     int                     TrailingSpaces;
1450     char                    LowerKeyword[128];
1451     int                     KeywordLength;
1452
1453
1454     switch (Type)
1455     {
1456     case SRC_TYPE_STRUCT:
1457
1458         InsertString = "struct ";
1459         break;
1460
1461     case SRC_TYPE_UNION:
1462
1463         InsertString = "union ";
1464         break;
1465
1466     default:
1467
1468         return;
1469     }
1470
1471     strcpy (LowerKeyword, Keyword);
1472     AsStrlwr (LowerKeyword);
1473
1474     SubBuffer = Buffer;
1475     SubString = Buffer;
1476     InsertLength = strlen (InsertString);
1477     KeywordLength = strlen (Keyword);
1478
1479
1480     while (SubString)
1481     {
1482         /* Find an instance of the keyword */
1483
1484         SubString = strstr (SubBuffer, LowerKeyword);
1485         if (!SubString)
1486         {
1487             return;
1488         }
1489
1490         SubBuffer = SubString;
1491
1492         /* Must be standalone word, not a substring */
1493
1494         if (AsMatchExactWord (SubString, KeywordLength))
1495         {
1496             /* Make sure the keyword isn't already prefixed with the insert */
1497
1498             if (!strncmp (SubString - InsertLength, InsertString, InsertLength))
1499             {
1500                 /* Add spaces if not already at the end-of-line */
1501
1502                 if (*(SubBuffer + KeywordLength) != '\n')
1503                 {
1504                     /* Already present, add spaces after to align structure members */
1505
1506 #if 0
1507 /* ONLY FOR C FILES */
1508                     AsInsertData (SubBuffer + KeywordLength, "        ", 8);
1509 #endif
1510                 }
1511                 goto Next;
1512             }
1513
1514             /* Make sure the keyword isn't at the end of a struct/union */
1515             /* Note: This code depends on a single space after the brace */
1516
1517             if (*(SubString - 2) == '}')
1518             {
1519                 goto Next;
1520             }
1521
1522             /* Prefix the keyword with the insert string */
1523
1524             Gbl_MadeChanges = TRUE;
1525
1526             /* Is there room for insertion */
1527
1528             EndKeyword = SubString + strlen (LowerKeyword);
1529
1530             TrailingSpaces = 0;
1531             while (EndKeyword[TrailingSpaces] == ' ')
1532             {
1533                 TrailingSpaces++;
1534             }
1535
1536             /*
1537              * Use "if (TrailingSpaces > 1)" if we want to ignore casts
1538              */
1539             SubBuffer = SubString + InsertLength;
1540
1541             if (TrailingSpaces > InsertLength)
1542             {
1543                 /* Insert the keyword */
1544
1545                 memmove (SubBuffer, SubString, KeywordLength);
1546
1547                 /* Insert the keyword */
1548
1549                 memmove (SubString, InsertString, InsertLength);
1550             }
1551             else
1552             {
1553                 AsInsertData (SubString, InsertString, InsertLength);
1554             }
1555         }
1556
1557 Next:
1558         SubBuffer += KeywordLength;
1559     }
1560 }
1561
1562 #ifdef ACPI_FUTURE_IMPLEMENTATION
1563 /******************************************************************************
1564  *
1565  * FUNCTION:    AsTrimComments
1566  *
1567  * DESCRIPTION: Finds 3-line comments with only a single line of text
1568  *
1569  ******************************************************************************/
1570
1571 void
1572 AsTrimComments (
1573     char                    *Buffer,
1574     char                    *Filename)
1575 {
1576     char                    *SubBuffer = Buffer;
1577     char                    *Ptr1;
1578     char                    *Ptr2;
1579     UINT32                  LineCount;
1580     UINT32                  ShortCommentCount = 0;
1581
1582
1583     while (1)
1584     {
1585         /* Find comment open, within procedure level */
1586
1587         SubBuffer = strstr (SubBuffer, "    /*");
1588         if (!SubBuffer)
1589         {
1590             goto Exit;
1591         }
1592
1593         /* Find comment terminator */
1594
1595         Ptr1 = strstr (SubBuffer, "*/");
1596         if (!Ptr1)
1597         {
1598             goto Exit;
1599         }
1600
1601         /* Find next EOL (from original buffer) */
1602
1603         Ptr2 = strstr (SubBuffer, "\n");
1604         if (!Ptr2)
1605         {
1606             goto Exit;
1607         }
1608
1609         /* Ignore one-line comments */
1610
1611         if (Ptr1 < Ptr2)
1612         {
1613             /* Normal comment, ignore and continue; */
1614
1615             SubBuffer = Ptr2;
1616             continue;
1617         }
1618
1619         /* Examine multi-line comment */
1620
1621         LineCount = 1;
1622         while (Ptr1 > Ptr2)
1623         {
1624             /* Find next EOL */
1625
1626             Ptr2++;
1627             Ptr2 = strstr (Ptr2, "\n");
1628             if (!Ptr2)
1629             {
1630                 goto Exit;
1631             }
1632
1633             LineCount++;
1634         }
1635
1636         SubBuffer = Ptr1;
1637
1638         if (LineCount <= 3)
1639         {
1640             ShortCommentCount++;
1641         }
1642     }
1643
1644
1645 Exit:
1646
1647     if (ShortCommentCount)
1648     {
1649         AsPrint ("Short Comments found", ShortCommentCount, Filename);
1650     }
1651 }
1652 #endif