1
2/******************************************************************************
3 *
4 * Module Name: asmain - Main module for the acpi source processor utility
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions, and the following disclaimer,
17 *    without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 *    substantially similar to the "NO WARRANTY" disclaimer below
20 *    ("Disclaimer") and any redistribution must be conditioned upon
21 *    including a substantially similar Disclaimer requirement for further
22 *    binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 *    of any contributors may be used to endorse or promote products derived
25 *    from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46#include "acpisrc.h"
47#include "acapps.h"
48
49/* Local prototypes */
50
51int
52AsStricmp (
53    char                    *String1,
54    char                    *String2);
55
56int
57AsExaminePaths (
58    ACPI_CONVERSION_TABLE   *ConversionTable,
59    char                    *Source,
60    char                    *Target,
61    UINT32                  *SourceFileType);
62
63void
64AsDisplayStats (
65    void);
66
67void
68AsDisplayUsage (
69    void);
70
71/* Globals */
72
73UINT32                  Gbl_Tabs = 0;
74UINT32                  Gbl_MissingBraces = 0;
75UINT32                  Gbl_NonAnsiComments = 0;
76UINT32                  Gbl_Files = 0;
77UINT32                  Gbl_WhiteLines = 0;
78UINT32                  Gbl_CommentLines = 0;
79UINT32                  Gbl_SourceLines = 0;
80UINT32                  Gbl_LongLines = 0;
81UINT32                  Gbl_TotalLines = 0;
82UINT32                  Gbl_TotalSize = 0;
83UINT32                  Gbl_HeaderLines = 0;
84UINT32                  Gbl_HeaderSize = 0;
85void                    *Gbl_StructDefs = NULL;
86
87struct stat             Gbl_StatBuf;
88char                    *Gbl_FileBuffer;
89UINT32                  Gbl_FileSize;
90UINT32                  Gbl_FileType;
91BOOLEAN                 Gbl_VerboseMode = FALSE;
92BOOLEAN                 Gbl_QuietMode = FALSE;
93BOOLEAN                 Gbl_BatchMode = FALSE;
94BOOLEAN                 Gbl_DebugStatementsMode = FALSE;
95BOOLEAN                 Gbl_MadeChanges = FALSE;
96BOOLEAN                 Gbl_Overwrite = FALSE;
97BOOLEAN                 Gbl_WidenDeclarations = FALSE;
98BOOLEAN                 Gbl_IgnoreLoneLineFeeds = FALSE;
99BOOLEAN                 Gbl_HasLoneLineFeeds = FALSE;
100
101
102/******************************************************************************
103 *
104 * FUNCTION:    AsStricmp
105 *
106 * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
107 *              strings with no case sensitivity)
108 *
109 ******************************************************************************/
110
111int
112AsStricmp (
113    char                    *String1,
114    char                    *String2)
115{
116    int                     c1;
117    int                     c2;
118
119
120    do
121    {
122        c1 = tolower ((int) *String1);
123        c2 = tolower ((int) *String2);
124
125        String1++;
126        String2++;
127    }
128    while ((c1 == c2) && (c1));
129
130    return (c1 - c2);
131}
132
133
134/******************************************************************************
135 *
136 * FUNCTION:    AsExaminePaths
137 *
138 * DESCRIPTION: Source and Target pathname verification and handling
139 *
140 ******************************************************************************/
141
142int
143AsExaminePaths (
144    ACPI_CONVERSION_TABLE   *ConversionTable,
145    char                    *Source,
146    char                    *Target,
147    UINT32                  *SourceFileType)
148{
149    int                     Status;
150    char                    Response;
151
152
153    Status = stat (Source, &Gbl_StatBuf);
154    if (Status)
155    {
156        printf ("Source path \"%s\" does not exist\n", Source);
157        return -1;
158    }
159
160    /* Return the filetype -- file or a directory */
161
162    *SourceFileType = 0;
163    if (Gbl_StatBuf.st_mode & S_IFDIR)
164    {
165        *SourceFileType = S_IFDIR;
166    }
167
168    /*
169     * If we are in no-output mode or in batch mode, we are done
170     */
171    if ((ConversionTable->Flags & FLG_NO_FILE_OUTPUT) ||
172        (Gbl_BatchMode))
173    {
174        return 0;
175    }
176
177    if (!AsStricmp (Source, Target))
178    {
179        printf ("Target path is the same as the source path, overwrite?\n");
180        scanf ("%c", &Response);
181
182        /* Check response */
183
184        if ((char) Response != 'y')
185        {
186            return -1;
187        }
188
189        Gbl_Overwrite = TRUE;
190    }
191    else
192    {
193        Status = stat (Target, &Gbl_StatBuf);
194        if (!Status)
195        {
196            printf ("Target path already exists, overwrite?\n");
197            scanf ("%c", &Response);
198
199            /* Check response */
200
201            if ((char) Response != 'y')
202            {
203                return -1;
204            }
205        }
206    }
207
208    return 0;
209}
210
211
212/******************************************************************************
213 *
214 * FUNCTION:    AsDisplayStats
215 *
216 * DESCRIPTION: Display global statistics gathered during translation
217 *
218 ******************************************************************************/
219
220void
221AsDisplayStats (
222    void)
223{
224
225    if (Gbl_QuietMode)
226    {
227        return;
228    }
229
230    printf ("\nAcpiSrc statistics:\n\n");
231    printf ("%8u Files processed\n", Gbl_Files);
232    printf ("%8u Total bytes (%.1fK/file)\n",
233        Gbl_TotalSize, ((double) Gbl_TotalSize/Gbl_Files)/1024);
234    printf ("%8u Tabs found\n", Gbl_Tabs);
235    printf ("%8u Missing if/else braces\n", Gbl_MissingBraces);
236    printf ("%8u Non-ANSI comments found\n", Gbl_NonAnsiComments);
237    printf ("%8u Total Lines\n", Gbl_TotalLines);
238    printf ("%8u Lines of code\n", Gbl_SourceLines);
239    printf ("%8u Lines of non-comment whitespace\n", Gbl_WhiteLines);
240    printf ("%8u Lines of comments\n", Gbl_CommentLines);
241    printf ("%8u Long lines found\n", Gbl_LongLines);
242    printf ("%8.1f Ratio of code to whitespace\n",
243        ((float) Gbl_SourceLines / (float) Gbl_WhiteLines));
244    printf ("%8.1f Ratio of code to comments\n",
245        ((float) Gbl_SourceLines / (float) (Gbl_CommentLines + Gbl_NonAnsiComments)));
246    printf ("         %u%% code, %u%% comments, %u%% whitespace, %u%% headers\n",
247        (Gbl_SourceLines * 100) / Gbl_TotalLines,
248        (Gbl_CommentLines * 100) / Gbl_TotalLines,
249        (Gbl_WhiteLines * 100) / Gbl_TotalLines,
250        (Gbl_HeaderLines * 100) / Gbl_TotalLines);
251    return;
252}
253
254
255/******************************************************************************
256 *
257 * FUNCTION:    AsDisplayUsage
258 *
259 * DESCRIPTION: Usage message
260 *
261 ******************************************************************************/
262
263void
264AsDisplayUsage (
265    void)
266{
267
268    printf ("\n");
269    printf ("Usage: acpisrc [-c|l|u] [-dsvy] <SourceDir> <DestinationDir>\n\n");
270    printf ("Where: -c          Generate cleaned version of the source\n");
271    printf ("       -h          Insert dual-license header into all modules\n");
272    printf ("       -l          Generate Linux version of the source\n");
273    printf ("       -u          Generate Custom source translation\n");
274    printf ("\n");
275    printf ("       -d          Leave debug statements in code\n");
276    printf ("       -s          Generate source statistics only\n");
277    printf ("       -v          Verbose mode\n");
278    printf ("       -y          Suppress file overwrite prompts\n");
279    printf ("\n");
280    return;
281}
282
283
284/******************************************************************************
285 *
286 * FUNCTION:    main
287 *
288 * DESCRIPTION: C main function
289 *
290 ******************************************************************************/
291
292int ACPI_SYSTEM_XFACE
293main (
294    int                     argc,
295    char                    *argv[])
296{
297    int                     j;
298    ACPI_CONVERSION_TABLE   *ConversionTable = NULL;
299    char                    *SourcePath;
300    char                    *TargetPath;
301    UINT32                  FileType;
302
303
304    printf (ACPI_COMMON_SIGNON ("ACPI Source Code Conversion Utility"));
305
306    if (argc < 2)
307    {
308        AsDisplayUsage ();
309        return 0;
310    }
311
312    /* Command line options */
313
314    while ((j = AcpiGetopt (argc, argv, "cdhlqsuvy")) != EOF) switch(j)
315    {
316    case 'l':
317        /* Linux code generation */
318
319        printf ("Creating Linux source code\n");
320        ConversionTable = &LinuxConversionTable;
321        Gbl_WidenDeclarations = TRUE;
322        Gbl_IgnoreLoneLineFeeds = TRUE;
323        break;
324
325    case 'c':
326        /* Cleanup code */
327
328        printf ("Code cleanup\n");
329        ConversionTable = &CleanupConversionTable;
330        break;
331
332    case 'h':
333        /* Inject Dual-license header */
334
335        printf ("Inserting Dual-license header to all modules\n");
336        ConversionTable = &LicenseConversionTable;
337        break;
338
339    case 's':
340        /* Statistics only */
341
342        break;
343
344    case 'u':
345        /* custom conversion  */
346
347        printf ("Custom source translation\n");
348        ConversionTable = &CustomConversionTable;
349        break;
350
351    case 'v':
352        /* Verbose mode */
353
354        Gbl_VerboseMode = TRUE;
355        break;
356
357    case 'y':
358        /* Batch mode */
359
360        Gbl_BatchMode = TRUE;
361        break;
362
363    case 'd':
364        /* Leave debug statements in */
365
366        Gbl_DebugStatementsMode = TRUE;
367        break;
368
369    case 'q':
370        /* Quiet mode */
371
372        Gbl_QuietMode = TRUE;
373        break;
374
375    default:
376        AsDisplayUsage ();
377        return -1;
378    }
379
380
381    SourcePath = argv[AcpiGbl_Optind];
382    if (!SourcePath)
383    {
384        printf ("Missing source path\n");
385        AsDisplayUsage ();
386        return -1;
387    }
388
389    TargetPath = argv[AcpiGbl_Optind+1];
390
391    if (!ConversionTable)
392    {
393        /* Just generate statistics.  Ignore target path */
394
395        TargetPath = SourcePath;
396
397        printf ("Source code statistics only\n");
398        ConversionTable = &StatsConversionTable;
399    }
400    else if (!TargetPath)
401    {
402        TargetPath = SourcePath;
403    }
404
405    if (Gbl_DebugStatementsMode)
406    {
407        ConversionTable->SourceFunctions &= ~CVT_REMOVE_DEBUG_MACROS;
408    }
409
410    /* Check source and target paths and files */
411
412    if (AsExaminePaths (ConversionTable, SourcePath, TargetPath, &FileType))
413    {
414        return -1;
415    }
416
417    /* Source/target can be either directories or a files */
418
419    if (FileType == S_IFDIR)
420    {
421        /* Process the directory tree */
422
423        AsProcessTree (ConversionTable, SourcePath, TargetPath);
424    }
425    else
426    {
427        /* Process a single file */
428
429        /* Differentiate between source and header files */
430
431        if (strstr (SourcePath, ".h"))
432        {
433            AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, SourcePath, FILE_TYPE_HEADER);
434        }
435        else
436        {
437            AsProcessOneFile (ConversionTable, NULL, TargetPath, 0, SourcePath, FILE_TYPE_SOURCE);
438        }
439    }
440
441    /* Always display final summary and stats */
442
443    AsDisplayStats ();
444
445    return 0;
446}
447