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