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