Update ACPI build wrappers to use new ACPICA(20050309) code.
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050211 / tools / acpisrc / asconvrt.c
1
2 /******************************************************************************
3  *
4  * Module Name: asconvrt - Source conversion code
5  *              $Revision: 50 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
14  * All rights reserved.
15  *
16  * 2. License
17  *
18  * 2.1. This is your license from Intel Corp. under its intellectual property
19  * rights.  You may have additional license terms from the party that provided
20  * you this software, covering your right to use that party's intellectual
21  * property rights.
22  *
23  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24  * copy of the source code appearing in this file ("Covered Code") an
25  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26  * base code distributed originally by Intel ("Original Intel Code") to copy,
27  * make derivatives, distribute, use and display any portion of the Covered
28  * Code in any form, with the right to sublicense such rights; and
29  *
30  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31  * license (with the right to sublicense), under only those claims of Intel
32  * patents that are infringed by the Original Intel Code, to make, use, sell,
33  * offer to sell, and import the Covered Code and derivative works thereof
34  * solely to the minimum extent necessary to exercise the above copyright
35  * license, and in no event shall the patent license extend to any additions
36  * to or modifications of the Original Intel Code.  No other license or right
37  * is granted directly or by implication, estoppel or otherwise;
38  *
39  * The above copyright and patent license is granted only if the following
40  * conditions are met:
41  *
42  * 3. Conditions
43  *
44  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45  * Redistribution of source code of any substantial portion of the Covered
46  * Code or modification with rights to further distribute source must include
47  * the above Copyright Notice, the above License, this list of Conditions,
48  * and the following Disclaimer and Export Compliance provision.  In addition,
49  * Licensee must cause all Covered Code to which Licensee contributes to
50  * contain a file documenting the changes Licensee made to create that Covered
51  * Code and the date of any change.  Licensee must include in that file the
52  * documentation of any changes made by any predecessor Licensee.  Licensee
53  * must include a prominent statement that the modification is derived,
54  * directly or indirectly, from Original Intel Code.
55  *
56  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57  * Redistribution of source code of any substantial portion of the Covered
58  * Code or modification without rights to further distribute source must
59  * include the following Disclaimer and Export Compliance provision in the
60  * documentation and/or other materials provided with distribution.  In
61  * addition, Licensee may not authorize further sublicense of source of any
62  * portion of the Covered Code, and must include terms to the effect that the
63  * license from Licensee to its licensee is limited to the intellectual
64  * property embodied in the software Licensee provides to its licensee, and
65  * not to intellectual property embodied in modifications its licensee may
66  * make.
67  *
68  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69  * substantial portion of the Covered Code or modification must reproduce the
70  * above Copyright Notice, and the following Disclaimer and Export Compliance
71  * provision in the documentation and/or other materials provided with the
72  * distribution.
73  *
74  * 3.4. Intel retains all right, title, and interest in and to the Original
75  * Intel Code.
76  *
77  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78  * Intel shall be used in advertising or otherwise to promote the sale, use or
79  * other dealings in products derived from or relating to the Covered Code
80  * without prior written authorization from Intel.
81  *
82  * 4. Disclaimer and Export Compliance
83  *
84  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90  * PARTICULAR PURPOSE.
91  *
92  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99  * LIMITED REMEDY.
100  *
101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102  * software or system incorporating such software without first obtaining any
103  * required license or other approval from the U. S. Department of Commerce or
104  * any other agency or department of the United States Government.  In the
105  * event Licensee exports any such software from the United States or
106  * re-exports any such software from a foreign destination, Licensee shall
107  * ensure that the distribution and export/re-export of the software is in
108  * compliance with all laws, regulations, orders, or other restrictions of the
109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110  * any of its subsidiaries will export/re-export any technical data, process,
111  * software, or service, directly or indirectly, to any country for which the
112  * United States government or any agency thereof requires an export license,
113  * other governmental approval, or letter of assurance, without first obtaining
114  * such license, approval or letter.
115  *
116  *****************************************************************************/
117
118 #include "acpisrc.h"
119
120
121 /* Opening signature of the Intel legal header */
122
123 char        *HeaderBegin = "/******************************************************************************\n *\n * 1. Copyright Notice";
124
125
126 /******************************************************************************
127  *
128  * FUNCTION:    AsMatchExactWord
129  *
130  * DESCRIPTION: Check previous and next characters for whitespace
131  *
132  ******************************************************************************/
133
134 BOOLEAN
135 AsMatchExactWord (
136     char                    *Word,
137     UINT32                  WordLength)
138 {
139     char                    NextChar;
140     char                    PrevChar;
141
142
143     NextChar = Word[WordLength];
144     PrevChar = * (Word -1);
145
146     if (isalnum (NextChar) ||
147         (NextChar == '_')  ||
148         isalnum (PrevChar) ||
149         (PrevChar == '_'))
150     {
151         return (FALSE);
152     }
153
154     return (TRUE);
155 }
156
157
158 /******************************************************************************
159  *
160  * FUNCTION:    AsPrint
161  *
162  * DESCRIPTION: Common formatted print
163  *
164  ******************************************************************************/
165
166 void
167 AsPrint (
168     char                    *Message,
169     UINT32                  Count,
170     char                    *Filename)
171 {
172
173
174     printf ("-- %4u %28.28s : %s\n", Count, Message, Filename);
175 }
176
177
178 /******************************************************************************
179  *
180  * FUNCTION:    AsCheckAndSkipLiterals
181  *
182  * DESCRIPTION: Generic routine to skip comments and quoted string literals.
183  *              Keeps a line count.
184  *
185  ******************************************************************************/
186
187 char *
188 AsCheckAndSkipLiterals (
189     char                    *Buffer,
190     UINT32                  *TotalLines)
191 {
192     UINT32                  NewLines = 0;
193     char                    *SubBuffer = Buffer;
194     char                    *LiteralEnd;
195
196
197     /* Ignore comments */
198
199     if ((SubBuffer[0] == '/') &&
200         (SubBuffer[1] == '*'))
201     {
202         LiteralEnd = strstr (SubBuffer, "*/");
203         SubBuffer += 2;     /* Get past comment opening */
204
205         if (!LiteralEnd)
206         {
207             return SubBuffer;
208         }
209
210         while (SubBuffer < LiteralEnd)
211         {
212             if (*SubBuffer == '\n')
213             {
214                 NewLines++;
215             }
216
217             SubBuffer++;
218         }
219
220         SubBuffer += 2;     /* Get past comment close */
221     }
222
223     /* Ignore quoted strings */
224
225     else if (*SubBuffer == '\"')
226     {
227         SubBuffer++;
228         LiteralEnd = AsSkipPastChar (SubBuffer, '\"');
229         if (!LiteralEnd)
230         {
231             return SubBuffer;
232         }
233     }
234
235     if (TotalLines)
236     {
237         (*TotalLines) += NewLines;
238     }
239     return SubBuffer;
240 }
241
242
243 /******************************************************************************
244  *
245  * FUNCTION:    AsAsCheckForBraces
246  *
247  * DESCRIPTION: Check for an open brace after each if statement
248  *
249  ******************************************************************************/
250
251 void
252 AsCheckForBraces (
253     char                    *Buffer,
254     char                    *Filename)
255 {
256     char                    *SubBuffer = Buffer;
257     char                    *NextBrace;
258     char                    *NextSemicolon;
259     char                    *NextIf;
260     UINT32                  TotalLines = 1;
261
262
263     while (*SubBuffer)
264     {
265
266         SubBuffer = AsCheckAndSkipLiterals (SubBuffer, &TotalLines);
267
268         if (*SubBuffer == '\n')
269         {
270             TotalLines++;
271         }
272         else if (!(strncmp (" if", SubBuffer, 3)))
273         {
274             SubBuffer += 2;
275             NextBrace = strstr (SubBuffer, "{");
276             NextSemicolon = strstr (SubBuffer, ";");
277             NextIf = strstr (SubBuffer, " if");
278
279             if ((!NextBrace) ||
280                (NextSemicolon && (NextBrace > NextSemicolon)) ||
281                (NextIf && (NextBrace > NextIf)))
282             {
283                 Gbl_MissingBraces++;
284                 printf ("Missing braces for <if>, line %d: %s\n", TotalLines, Filename);
285             }
286         }
287         else if (!(strncmp (" else if", SubBuffer, 8)))
288         {
289             SubBuffer += 7;
290             NextBrace = strstr (SubBuffer, "{");
291             NextSemicolon = strstr (SubBuffer, ";");
292             NextIf = strstr (SubBuffer, " if");
293
294             if ((!NextBrace) ||
295                (NextSemicolon && (NextBrace > NextSemicolon)) ||
296                (NextIf && (NextBrace > NextIf)))
297             {
298                 Gbl_MissingBraces++;
299                 printf ("Missing braces for <if>, line %d: %s\n", TotalLines, Filename);
300             }
301         }
302         else if (!(strncmp (" else", SubBuffer, 5)))
303         {
304             SubBuffer += 4;
305             NextBrace = strstr (SubBuffer, "{");
306             NextSemicolon = strstr (SubBuffer, ";");
307             NextIf = strstr (SubBuffer, " if");
308
309             if ((!NextBrace) ||
310                (NextSemicolon && (NextBrace > NextSemicolon)) ||
311                (NextIf && (NextBrace > NextIf)))
312             {
313                 Gbl_MissingBraces++;
314                 printf ("Missing braces for <else>, line %d: %s\n", TotalLines, Filename);
315             }
316         }
317
318         SubBuffer++;
319     }
320 }
321
322
323 /******************************************************************************
324  *
325  * FUNCTION:    AsTrimLines
326  *
327  * DESCRIPTION: Remove extra blanks from the end of source lines.  Does not
328  *              check for tabs.
329  *
330  ******************************************************************************/
331
332 void
333 AsTrimLines (
334     char                    *Buffer,
335     char                    *Filename)
336 {
337     char                    *SubBuffer = Buffer;
338     char                    *StartWhiteSpace = NULL;
339     UINT32                  SpaceCount = 0;
340
341
342     while (*SubBuffer)
343     {
344         while (*SubBuffer != '\n')
345         {
346             if (!*SubBuffer)
347             {
348                 goto Exit;
349             }
350
351             if (*SubBuffer == ' ')
352             {
353                 if (!StartWhiteSpace)
354                 {
355                     StartWhiteSpace = SubBuffer;
356                 }
357             }
358             else
359             {
360                 StartWhiteSpace = NULL;
361             }
362
363             SubBuffer++;
364         }
365
366         if (StartWhiteSpace)
367         {
368             SpaceCount += (SubBuffer - StartWhiteSpace);
369
370             /* Remove the spaces */
371
372             SubBuffer = AsRemoveData (StartWhiteSpace, SubBuffer);
373             StartWhiteSpace = NULL;
374         }
375
376         SubBuffer++;
377     }
378
379
380 Exit:
381     if (SpaceCount)
382     {
383         Gbl_MadeChanges = TRUE;
384         AsPrint ("Extraneous spaces removed", SpaceCount, Filename);
385     }
386 }
387
388
389 /******************************************************************************
390  *
391  * FUNCTION:    AsTrimWhitespace
392  *
393  * DESCRIPTION: Remove "excess" blank lines - any more than 2 blank lines.
394  *              this can happen during the translation when lines are removed.
395  *
396  ******************************************************************************/
397
398 void
399 AsTrimWhitespace (
400     char                    *Buffer)
401 {
402     int                     ReplaceCount = 1;
403
404
405     while (ReplaceCount)
406     {
407         ReplaceCount = AsReplaceString ("\n\n\n\n", "\n\n\n", REPLACE_SUBSTRINGS, Buffer);
408     }
409 }
410
411
412 /******************************************************************************
413  *
414  * FUNCTION:    AsReplaceHeader
415  *
416  * DESCRIPTION: Replace the default Intel legal header with a new header
417  *
418  ******************************************************************************/
419
420 void
421 AsReplaceHeader (
422     char                    *Buffer,
423     char                    *NewHeader)
424 {
425     char                    *SubBuffer;
426     char                    *TokenEnd;
427
428
429     /* Find the original header */
430
431     SubBuffer = strstr (Buffer, HeaderBegin);
432     if (!SubBuffer)
433     {
434         return;
435     }
436
437     /* Find the end of the original header */
438
439     TokenEnd = strstr (SubBuffer, "*/");
440     TokenEnd = AsSkipPastChar (TokenEnd, '\n');
441
442     /* Delete old header, insert new one */
443
444     AsReplaceData (SubBuffer, TokenEnd - SubBuffer, NewHeader, strlen (NewHeader));
445 }
446
447
448 /******************************************************************************
449  *
450  * FUNCTION:    AsReplaceString
451  *
452  * DESCRIPTION: Replace all instances of a target string with a replacement
453  *              string.  Returns count of the strings replaced.
454  *
455  ******************************************************************************/
456
457 int
458 AsReplaceString (
459     char                    *Target,
460     char                    *Replacement,
461     UINT8                   Type,
462     char                    *Buffer)
463 {
464     char                    *SubString1;
465     char                    *SubString2;
466     char                    *SubBuffer;
467     int                     TargetLength;
468     int                     ReplacementLength;
469     int                     ReplaceCount = 0;
470
471
472     TargetLength = strlen (Target);
473     ReplacementLength = strlen (Replacement);
474
475     SubBuffer = Buffer;
476     SubString1 = Buffer;
477
478     while (SubString1)
479     {
480         /* Find the target string */
481
482         SubString1 = strstr (SubBuffer, Target);
483         if (!SubString1)
484         {
485             return ReplaceCount;
486         }
487
488         /*
489          * Check for translation escape string -- means to ignore
490          * blocks of code while replacing
491          */
492
493         SubString2 = strstr (SubBuffer, "/*!");
494
495         if ((SubString2) &&
496             (SubString2 < SubString1))
497         {
498             /* Find end of the escape block starting at "Substring2" */
499
500             SubString2 = strstr (SubString2, "!*/");
501             if (!SubString2)
502             {
503                 /* Didn't find terminator */
504
505                 return ReplaceCount;
506             }
507
508             /* Move buffer to end of escape block and continue */
509
510             SubBuffer = SubString2;
511         }
512
513         /* Do the actual replace if the target was found */
514
515         else
516         {
517             if ((Type & REPLACE_MASK) == REPLACE_WHOLE_WORD)
518             {
519                 if (!AsMatchExactWord (SubString1, TargetLength))
520                 {
521                     SubBuffer = SubString1 + 1;
522                     continue;
523                 }
524             }
525
526             SubBuffer = AsReplaceData (SubString1, TargetLength, Replacement, ReplacementLength);
527 /*
528             if (((Type & INDENT_MASK) == EXTRA_INDENT_C) &&
529                 (Gbl_FileType == FILE_TYPE_SOURCE))
530             {
531                 SubBuffer = AsReplaceData (SubBuffer, 0, "    ", 4);
532             }
533 */
534
535             ReplaceCount++;
536         }
537     }
538
539     return ReplaceCount;
540 }
541
542
543 /******************************************************************************
544  *
545  * FUNCTION:    AsConvertToLineFeeds
546  *
547  * DESCRIPTION:
548  *
549  ******************************************************************************/
550
551 void
552 AsConvertToLineFeeds (
553     char                    *Buffer)
554 {
555     char                    *SubString;
556     char                    *SubBuffer;
557
558
559     SubBuffer = Buffer;
560     SubString = Buffer;
561
562     while (SubString)
563     {
564         /* Find the target string */
565
566         SubString = strstr (SubBuffer, "\r\n");
567         if (!SubString)
568         {
569             return;
570         }
571
572         SubBuffer = AsReplaceData (SubString, 1, NULL, 0);
573     }
574     return;
575 }
576
577
578 /******************************************************************************
579  *
580  * FUNCTION:    AsInsertCarriageReturns
581  *
582  * DESCRIPTION:
583  *
584  ******************************************************************************/
585
586 void
587 AsInsertCarriageReturns (
588     char                    *Buffer)
589 {
590     char                    *SubString;
591     char                    *SubBuffer;
592
593
594     SubBuffer = Buffer;
595     SubString = Buffer;
596
597     while (SubString)
598     {
599         /* Find the target string */
600
601         SubString = strstr (SubBuffer, "\n");
602         if (!SubString)
603         {
604             return;
605         }
606
607         SubBuffer = AsInsertData (SubString, "\r", 1);
608         SubBuffer += 1;
609     }
610     return;
611 }
612
613
614 /******************************************************************************
615  *
616  * FUNCTION:    AsBracesOnSameLine
617  *
618  * DESCRIPTION: Move opening braces up to the same line as an if, for, else,
619  *              or while statement (leave function opening brace on separate
620  *              line).
621  *
622  ******************************************************************************/
623
624 void
625 AsBracesOnSameLine (
626     char                    *Buffer)
627 {
628     UINT32                  Length;
629     char                    *SubBuffer = Buffer;
630     char                    *Beginning;
631     char                    *StartOfThisLine;
632     BOOLEAN                 BlockBegin = TRUE;
633
634
635     while (*SubBuffer)
636     {
637         /* Ignore comments */
638
639         if ((SubBuffer[0] == '/') &&
640             (SubBuffer[1] == '*'))
641         {
642             SubBuffer = strstr (SubBuffer, "*/");
643             if (!SubBuffer)
644             {
645                 return;
646             }
647
648             SubBuffer += 2;
649             continue;
650         }
651
652         /* Ignore quoted strings */
653
654         if (*SubBuffer == '\"')
655         {
656             SubBuffer++;
657             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
658             if (!SubBuffer)
659             {
660                 return;
661             }
662         }
663
664         if (!strncmp ("\n}", SubBuffer, 2))
665         {
666             /*
667              * A newline followed by a closing brace closes a function
668              * or struct or initializer block
669              */
670             BlockBegin = TRUE;
671         }
672
673         /* Move every standalone brace up to the previous line */
674
675         if (*SubBuffer == '{')
676         {
677             if (BlockBegin)
678             {
679                 BlockBegin = FALSE;
680             }
681             else
682             {
683                 /*
684                  * Backup to previous non-whitespace
685                  */
686                 Beginning = SubBuffer - 1;
687                 while ((*Beginning == ' ')   ||
688                        (*Beginning == '\n'))
689                 {
690                     Beginning--;
691                 }
692
693                 StartOfThisLine = Beginning;
694                 while (*StartOfThisLine != '\n')
695                 {
696                     StartOfThisLine--;
697                 }
698
699                 /*
700                  * Move the brace up to the previous line, UNLESS:
701                  *
702                  * 1) There is a conditional compile on the line (starts with '#')
703                  * 2) Previous line ends with an '=' (Start of initializer block)
704                  * 3) Previous line ends with a comma (part of an init list)
705                  *
706                  */
707                 if ((StartOfThisLine[1] != '#') &&
708                     (*Beginning != '=') &&
709                     (*Beginning != ','))
710                 {
711                     Beginning++;
712                     SubBuffer++;
713                     Length = strlen (SubBuffer);
714
715                     Gbl_MadeChanges = TRUE;
716
717 #ifdef ADD_EXTRA_WHITESPACE
718                     AsReplaceData (Beginning, SubBuffer-Beginning, " {\n", 3);
719 #else
720                     AsReplaceData (Beginning, SubBuffer-Beginning, " {", 2);
721 #endif
722                 }
723             }
724         }
725
726         SubBuffer++;
727     }
728 }
729
730
731 /******************************************************************************
732  *
733  * FUNCTION:    AsTabify4
734  *
735  * DESCRIPTION: Convert the text to tabbed text.  Alignment of text is
736  *              preserved.
737  *
738  ******************************************************************************/
739
740 void
741 AsTabify4 (
742     char                    *Buffer)
743 {
744     char                    *SubBuffer = Buffer;
745     char                    *NewSubBuffer;
746     UINT32                  SpaceCount = 0;
747     UINT32                  Column = 0;
748
749
750     while (*SubBuffer)
751     {
752         if (*SubBuffer == '\n')
753         {
754             Column = 0;
755         }
756         else
757         {
758             Column++;
759         }
760
761         /* Ignore comments */
762
763         if ((SubBuffer[0] == '/') &&
764             (SubBuffer[1] == '*'))
765         {
766             SubBuffer = strstr (SubBuffer, "*/");
767             if (!SubBuffer)
768             {
769                 return;
770             }
771
772             SubBuffer += 2;
773             continue;
774         }
775
776         /* Ignore quoted strings */
777
778         if (*SubBuffer == '\"')
779         {
780             SubBuffer++;
781             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
782             if (!SubBuffer)
783             {
784                 return;
785             }
786             SpaceCount = 0;
787         }
788
789         if (*SubBuffer == ' ')
790         {
791             SpaceCount++;
792
793             if (SpaceCount >= 4)
794             {
795                 SpaceCount = 0;
796
797                 NewSubBuffer = (SubBuffer + 1) - 4;
798                 *NewSubBuffer = '\t';
799                 NewSubBuffer++;
800
801                 /* Remove the spaces */
802
803                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer + 1);
804             }
805
806             if ((Column % 4) == 0)
807             {
808                 SpaceCount = 0;
809             }
810         }
811         else
812         {
813             SpaceCount = 0;
814         }
815
816         SubBuffer++;
817     }
818 }
819
820
821 /******************************************************************************
822  *
823  * FUNCTION:    AsTabify8
824  *
825  * DESCRIPTION: Convert the text to tabbed text.  Alignment of text is
826  *              preserved.
827  *
828  ******************************************************************************/
829
830 void
831 AsTabify8 (
832     char                    *Buffer)
833 {
834     char                    *SubBuffer = Buffer;
835     char                    *NewSubBuffer;
836     char                    *CommentEnd = NULL;
837     UINT32                  SpaceCount = 0;
838     UINT32                  Column = 0;
839     UINT32                  TabCount = 0;
840     UINT32                  LastLineTabCount = 0;
841     UINT32                  LastLineColumnStart = 0;
842     UINT32                  ThisColumnStart = 0;
843     UINT32                  ThisTabCount =  0;
844     char                    *FirstNonBlank = NULL;
845
846
847     while (*SubBuffer)
848     {
849         if (*SubBuffer == '\n')
850         {
851             /* This is a standalone blank line */
852
853             FirstNonBlank = NULL;
854             Column = 0;
855             SpaceCount = 0;
856             TabCount = 0;
857             SubBuffer++;
858             continue;
859         }
860
861         if (!FirstNonBlank)
862         {
863             /* Find the first non-blank character on this line */
864
865             FirstNonBlank = SubBuffer;
866             while (*FirstNonBlank == ' ')
867             {
868                 FirstNonBlank++;
869             }
870
871             /*
872              * This mechanism limits the difference in tab counts from
873              * line to line.  It helps avoid the situation where a second
874              * continuation line (which was indented correctly for tabs=4) would
875              * get indented off the screen if we just blindly converted to tabs.
876              */
877             ThisColumnStart = FirstNonBlank - SubBuffer;
878
879             if (LastLineTabCount == 0)
880             {
881                 ThisTabCount = 0;
882             }
883             else if (ThisColumnStart == LastLineColumnStart)
884             {
885                 ThisTabCount = LastLineTabCount -1;
886             }
887             else
888             {
889                 ThisTabCount = LastLineTabCount + 1;
890             }
891         }
892
893         Column++;
894
895         /* Check if we are in a comment */
896
897         if ((SubBuffer[0] == '*') &&
898             (SubBuffer[1] == '/'))
899         {
900             SpaceCount = 0;
901             SubBuffer += 2;
902
903             if (*SubBuffer == '\n')
904             {
905                 if (TabCount > 0)
906                 {
907                     LastLineTabCount = TabCount;
908                     TabCount = 0;
909                 }
910                 FirstNonBlank = NULL;
911                 LastLineColumnStart = ThisColumnStart;
912                 SubBuffer++;
913             }
914
915             continue;
916         }
917
918         /* Check for comment open */
919
920         if ((SubBuffer[0] == '/') &&
921             (SubBuffer[1] == '*'))
922         {
923             /* Find the end of the comment, it must exist */
924
925             CommentEnd = strstr (SubBuffer, "*/");
926             if (!CommentEnd)
927             {
928                 return;
929             }
930
931             /* Toss the rest of this line or single-line comment */
932
933             while ((SubBuffer < CommentEnd) &&
934                    (*SubBuffer != '\n'))
935             {
936                 SubBuffer++;
937             }
938
939             if (*SubBuffer == '\n')
940             {
941                 if (TabCount > 0)
942                 {
943                     LastLineTabCount = TabCount;
944                     TabCount = 0;
945                 }
946                 FirstNonBlank = NULL;
947                 LastLineColumnStart = ThisColumnStart;
948             }
949
950             SpaceCount = 0;
951             continue;
952         }
953
954         /* Ignore quoted strings */
955
956         if ((!CommentEnd) && (*SubBuffer == '\"'))
957         {
958             SubBuffer++;
959             SubBuffer = AsSkipPastChar (SubBuffer, '\"');
960             if (!SubBuffer)
961             {
962                 return;
963             }
964             SpaceCount = 0;
965         }
966
967         if (*SubBuffer != ' ')
968         {
969             /* Not a space, skip to end of line */
970
971             SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
972             if (!SubBuffer)
973             {
974                 return;
975             }
976             if (TabCount > 0)
977             {
978                 LastLineTabCount = TabCount;
979                 TabCount = 0;
980             }
981
982             FirstNonBlank = NULL;
983             LastLineColumnStart = ThisColumnStart;
984             Column = 0;
985             SpaceCount = 0;
986         }
987         else
988         {
989             /* Another space */
990
991             SpaceCount++;
992
993             if (SpaceCount >= 4)
994             {
995                 /* Replace this group of spaces with a tab character */
996
997                 SpaceCount = 0;
998
999                 NewSubBuffer = SubBuffer - 3;
1000
1001                 if (TabCount <= ThisTabCount ? (ThisTabCount +1) : 0)
1002                 {
1003                     *NewSubBuffer = '\t';
1004                     NewSubBuffer++;
1005                     SubBuffer++;
1006                     TabCount++;
1007                 }
1008
1009                 /* Remove the spaces */
1010
1011                 SubBuffer = AsRemoveData (NewSubBuffer, SubBuffer);
1012                 continue;
1013             }
1014         }
1015
1016         SubBuffer++;
1017     }
1018 }
1019
1020
1021 /******************************************************************************
1022  *
1023  * FUNCTION:    AsCountLines
1024  *
1025  * DESCRIPTION: Count the number of lines in the input buffer.  Also count
1026  *              the number of long lines (lines longer than 80 chars).
1027  *
1028  ******************************************************************************/
1029
1030 UINT32
1031 AsCountLines (
1032     char                    *Buffer,
1033     char                    *Filename)
1034 {
1035     char                    *SubBuffer = Buffer;
1036     char                    *EndOfLine;
1037     UINT32                  LineCount = 0;
1038     UINT32                  LongLineCount = 0;
1039
1040
1041     while (*SubBuffer)
1042     {
1043         EndOfLine = AsSkipUntilChar (SubBuffer, '\n');
1044         if (!EndOfLine)
1045         {
1046             Gbl_TotalLines += LineCount;
1047             return LineCount;
1048         }
1049
1050         if ((EndOfLine - SubBuffer) > 80)
1051         {
1052             LongLineCount++;
1053         }
1054
1055         LineCount++;
1056         SubBuffer = EndOfLine + 1;
1057     }
1058
1059     if (LongLineCount)
1060     {
1061         VERBOSE_PRINT (("%d Lines longer than 80 found in %s\n", LongLineCount, Filename));
1062         Gbl_LongLines += LongLineCount;
1063     }
1064
1065     Gbl_TotalLines += LineCount;
1066     return LineCount;
1067 }
1068
1069
1070 /******************************************************************************
1071  *
1072  * FUNCTION:    AsCountTabs
1073  *
1074  * DESCRIPTION: Simply count the number of tabs in the input file buffer
1075  *
1076  ******************************************************************************/
1077
1078 void
1079 AsCountTabs (
1080     char                    *Buffer,
1081     char                    *Filename)
1082 {
1083     UINT32                  i;
1084     UINT32                  TabCount = 0;
1085
1086
1087     for (i = 0; Buffer[i]; i++)
1088     {
1089         if (Buffer[i] == '\t')
1090         {
1091             TabCount++;
1092         }
1093     }
1094
1095     if (TabCount)
1096     {
1097         AsPrint ("Tabs found", TabCount, Filename);
1098         Gbl_Tabs += TabCount;
1099     }
1100
1101     AsCountLines (Buffer, Filename);
1102 }
1103
1104
1105 /******************************************************************************
1106  *
1107  * FUNCTION:    AsCountNonAnsiComments
1108  *
1109  * DESCRIPTION: Count the number of "//" comments.  This type of comment is
1110  *              non-ANSI C.
1111  *
1112  ******************************************************************************/
1113
1114 void
1115 AsCountNonAnsiComments (
1116     char                    *Buffer,
1117     char                    *Filename)
1118 {
1119     char                    *SubBuffer = Buffer;
1120     UINT32                  CommentCount = 0;
1121
1122
1123     while (SubBuffer)
1124     {
1125         SubBuffer = strstr (SubBuffer, "//");
1126         if (SubBuffer)
1127         {
1128             CommentCount++;
1129             SubBuffer += 2;
1130         }
1131     }
1132
1133     if (CommentCount)
1134     {
1135         AsPrint ("Non-ANSI Comments found", CommentCount, Filename);
1136         Gbl_NonAnsiComments += CommentCount;
1137     }
1138 }
1139
1140
1141 /******************************************************************************
1142  *
1143  * FUNCTION:    AsCountSourceLines
1144  *
1145  * DESCRIPTION: Count the number of C source lines.  Defined by 1) not a
1146  *              comment, and 2) not a blank line.
1147  *
1148  ******************************************************************************/
1149
1150 void
1151 AsCountSourceLines (
1152     char                    *Buffer,
1153     char                    *Filename)
1154 {
1155     char                    *SubBuffer = Buffer;
1156     UINT32                  LineCount = 0;
1157     UINT32                  WhiteCount = 0;
1158     UINT32                  CommentCount = 0;
1159
1160
1161     while (*SubBuffer)
1162     {
1163         /* Ignore comments */
1164
1165         if ((SubBuffer[0] == '/') &&
1166             (SubBuffer[1] == '*'))
1167         {
1168             CommentCount++;
1169             SubBuffer += 2;
1170
1171             while (SubBuffer[0] && SubBuffer[1] &&
1172                     !(((SubBuffer[0] == '*') &&
1173                       (SubBuffer[1] == '/'))))
1174             {
1175                 if (SubBuffer[0] == '\n')
1176                 {
1177                     CommentCount++;
1178                 }
1179
1180                 SubBuffer++;
1181             }
1182         }
1183
1184         /* A linefeed followed by a non-linefeed is a valid source line */
1185
1186         else if ((SubBuffer[0] == '\n') &&
1187                  (SubBuffer[1] != '\n'))
1188         {
1189             LineCount++;
1190         }
1191
1192         /* Two back-to-back linefeeds indicate a whitespace line */
1193
1194         else if ((SubBuffer[0] == '\n') &&
1195                  (SubBuffer[1] == '\n'))
1196         {
1197             WhiteCount++;
1198         }
1199
1200         SubBuffer++;
1201     }
1202
1203     /* Adjust comment count for legal header */
1204
1205     CommentCount -= LINES_IN_LEGAL_HEADER;
1206
1207     Gbl_SourceLines += LineCount;
1208     Gbl_WhiteLines += WhiteCount;
1209     Gbl_CommentLines += CommentCount;
1210
1211     VERBOSE_PRINT (("%d Comment %d White %d Code %d Lines in %s\n",
1212                 CommentCount, WhiteCount, LineCount, LineCount+WhiteCount+CommentCount, Filename));
1213 }
1214
1215
1216 /******************************************************************************
1217  *
1218  * FUNCTION:    AsInsertPrefix
1219  *
1220  * DESCRIPTION: Insert struct or union prefixes
1221  *
1222  ******************************************************************************/
1223
1224 void
1225 AsInsertPrefix (
1226     char                    *Buffer,
1227     char                    *Keyword,
1228     UINT8                   Type)
1229 {
1230     char                    *SubString;
1231     char                    *SubBuffer;
1232     char                    *EndKeyword;
1233     int                     StrLength;
1234     int                     InsertLength;
1235     char                    *InsertString;
1236     int                     TrailingSpaces;
1237     char                    LowerKeyword[128];
1238     int                     KeywordLength;
1239
1240
1241     switch (Type)
1242     {
1243     case SRC_TYPE_STRUCT:
1244         InsertString = "struct ";
1245         break;
1246
1247     case SRC_TYPE_UNION:
1248         InsertString = "union ";
1249         break;
1250
1251     default:
1252         return;
1253     }
1254
1255     strcpy (LowerKeyword, Keyword);
1256     strlwr (LowerKeyword);
1257
1258     SubBuffer = Buffer;
1259     SubString = Buffer;
1260     InsertLength = strlen (InsertString);
1261     KeywordLength = strlen (Keyword);
1262
1263
1264     while (SubString)
1265     {
1266         /* Find an instance of the keyword */
1267
1268         SubString = strstr (SubBuffer, LowerKeyword);
1269
1270         if (!SubString)
1271         {
1272             return;
1273         }
1274
1275         SubBuffer = SubString;
1276
1277         /* Must be standalone word, not a substring */
1278
1279         if (AsMatchExactWord (SubString, KeywordLength))
1280         {
1281             /* Make sure the keyword isn't already prefixed with the insert */
1282
1283             if (!strncmp (SubString - InsertLength, InsertString, InsertLength))
1284             {
1285                 /* Add spaces if not already at the end-of-line */
1286
1287                 if (*(SubBuffer + KeywordLength) != '\n')
1288                 {
1289                     /* Already present, add spaces after to align structure members */
1290
1291                     AsInsertData (SubBuffer + KeywordLength, "        ", 8);
1292                 }
1293                 goto Next;
1294             }
1295
1296             /* Make sure the keyword isn't at the end of a struct/union */
1297             /* Note: This code depends on a single space after the brace */
1298
1299             if (*(SubString - 2) == '}')
1300             {
1301                 goto Next;
1302             }
1303
1304             /* Prefix the keyword with the insert string */
1305
1306             Gbl_MadeChanges = TRUE;
1307             StrLength = strlen (SubString);
1308
1309             /* Is there room for insertion */
1310
1311             EndKeyword = SubString + strlen (LowerKeyword);
1312
1313             TrailingSpaces = 0;
1314             while (EndKeyword[TrailingSpaces] == ' ')
1315             {
1316                 TrailingSpaces++;
1317             }
1318
1319             /*
1320              * Use "if (TrailingSpaces > 1)" if we want to ignore casts
1321              */
1322             SubBuffer = SubString + InsertLength;
1323
1324             if (TrailingSpaces > InsertLength)
1325             {
1326                 /* Insert the keyword */
1327
1328                 memmove (SubBuffer, SubString, KeywordLength);
1329
1330                 /* Insert the keyword */
1331
1332                 memmove (SubString, InsertString, InsertLength);
1333             }
1334             else
1335             {
1336                 AsInsertData (SubString, InsertString, InsertLength);
1337             }
1338         }
1339
1340 Next:
1341         SubBuffer += KeywordLength;
1342     }
1343 }
1344
1345