asconvrt.c revision 1.1.1.3 1 /******************************************************************************
2 *
3 * Module Name: asconvrt - Source conversion code
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2013, 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
1539