asloptions.c revision 250838
1/******************************************************************************
2 *
3 * Module Name: asloptions - compiler command line processing
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/compiler/aslcompiler.h>
45#include <contrib/dev/acpica/include/acapps.h>
46#include <contrib/dev/acpica/include/acdisasm.h>
47
48#define _COMPONENT          ACPI_COMPILER
49        ACPI_MODULE_NAME    ("asloption")
50
51
52/* Local prototypes */
53
54static int
55AslDoOptions (
56    int                     argc,
57    char                    **argv,
58    BOOLEAN                 IsResponseFile);
59
60static void
61AslMergeOptionTokens (
62    char                    *InBuffer,
63    char                    *OutBuffer);
64
65static int
66AslDoResponseFile (
67    char                    *Filename);
68
69
70#define ASL_TOKEN_SEPARATORS    " \t\n"
71#define ASL_SUPPORTED_OPTIONS   "@:b|c|d^D:e:fgh^i|I:l^m:no|p:P^r:s|t|T:G^v^w|x:z"
72
73
74/*******************************************************************************
75 *
76 * FUNCTION:    AslCommandLine
77 *
78 * PARAMETERS:  argc/argv
79 *
80 * RETURN:      Last argv index
81 *
82 * DESCRIPTION: Command line processing
83 *
84 ******************************************************************************/
85
86int
87AslCommandLine (
88    int                     argc,
89    char                    **argv)
90{
91    int                     BadCommandLine = 0;
92    ACPI_STATUS             Status;
93
94
95    /* Minimum command line contains at least the command and an input file */
96
97    if (argc < 2)
98    {
99        printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
100        Usage ();
101        exit (1);
102    }
103
104    /* Process all command line options */
105
106    BadCommandLine = AslDoOptions (argc, argv, FALSE);
107
108    if (Gbl_DoTemplates)
109    {
110        Status = DtCreateTemplates (Gbl_TemplateSignature);
111        if (ACPI_FAILURE (Status))
112        {
113            exit (-1);
114        }
115        exit (1);
116    }
117
118    /* Next parameter must be the input filename */
119
120    if (!argv[AcpiGbl_Optind] &&
121        !Gbl_DisasmFlag &&
122        !Gbl_GetAllTables)
123    {
124        printf ("Missing input filename\n");
125        BadCommandLine = TRUE;
126    }
127
128    if (Gbl_DoSignon)
129    {
130        printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
131        if (Gbl_IgnoreErrors)
132        {
133            printf ("Ignoring all errors, forcing AML file generation\n\n");
134        }
135    }
136
137    if (BadCommandLine)
138    {
139        printf ("\n");
140        Usage ();
141        exit (1);
142    }
143
144    return (AcpiGbl_Optind);
145}
146
147
148/*******************************************************************************
149 *
150 * FUNCTION:    AslDoOptions
151 *
152 * PARAMETERS:  argc/argv           - Standard argc/argv
153 *              IsResponseFile      - TRUE if executing a response file.
154 *
155 * RETURN:      Status
156 *
157 * DESCRIPTION: Command line option processing
158 *
159 ******************************************************************************/
160
161static int
162AslDoOptions (
163    int                     argc,
164    char                    **argv,
165    BOOLEAN                 IsResponseFile)
166{
167    ACPI_STATUS             Status;
168    UINT32                  j;
169
170
171    /* Get the command line options */
172
173    while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != EOF) switch (j)
174    {
175    case '@':   /* Begin a response file */
176
177        if (IsResponseFile)
178        {
179            printf ("Nested command files are not supported\n");
180            return (-1);
181        }
182
183        if (AslDoResponseFile (AcpiGbl_Optarg))
184        {
185            return (-1);
186        }
187        break;
188
189    case 'b':   /* Debug output options */
190
191        switch (AcpiGbl_Optarg[0])
192        {
193        case 'f':
194
195            AslCompilerdebug = 1; /* same as yydebug */
196            DtParserdebug = 1;
197            PrParserdebug = 1;
198            break;
199
200        case 't':
201
202            break;
203
204        default:
205
206            printf ("Unknown option: -b%s\n", AcpiGbl_Optarg);
207            return (-1);
208        }
209
210        /* Produce debug output file */
211
212        Gbl_DebugFlag = TRUE;
213        break;
214
215    case 'c':
216
217        switch (AcpiGbl_Optarg[0])
218        {
219        case 'r':
220
221            Gbl_NoResourceChecking = TRUE;
222            break;
223
224        default:
225
226            printf ("Unknown option: -c%s\n", AcpiGbl_Optarg);
227            return (-1);
228        }
229        break;
230
231    case 'd':   /* Disassembler */
232
233        switch (AcpiGbl_Optarg[0])
234        {
235        case '^':
236
237            Gbl_DoCompile = FALSE;
238            break;
239
240        case 'a':
241
242            Gbl_DoCompile = FALSE;
243            Gbl_DisassembleAll = TRUE;
244            break;
245
246        case 'b':   /* Do not convert buffers to resource descriptors */
247
248            AcpiGbl_NoResourceDisassembly = TRUE;
249            break;
250
251        case 'c':
252
253            break;
254
255        default:
256
257            printf ("Unknown option: -d%s\n", AcpiGbl_Optarg);
258            return (-1);
259        }
260
261        Gbl_DisasmFlag = TRUE;
262        break;
263
264    case 'D':   /* Define a symbol */
265
266        PrAddDefine (AcpiGbl_Optarg, NULL, TRUE);
267        break;
268
269    case 'e':   /* External files for disassembler */
270
271        Status = AcpiDmAddToExternalFileList (AcpiGbl_Optarg);
272        if (ACPI_FAILURE (Status))
273        {
274            printf ("Could not add %s to external list\n", AcpiGbl_Optarg);
275            return (-1);
276        }
277        break;
278
279    case 'f':   /* Ignore errors and force creation of aml file */
280
281        Gbl_IgnoreErrors = TRUE;
282        break;
283
284    case 'G':
285
286        Gbl_CompileGeneric = TRUE;
287        break;
288
289    case 'g':   /* Get all ACPI tables */
290
291        Gbl_GetAllTables = TRUE;
292        Gbl_DoCompile = FALSE;
293        break;
294
295    case 'h':
296
297        switch (AcpiGbl_Optarg[0])
298        {
299        case '^':
300
301            Usage ();
302            exit (0);
303
304        case 'c':
305
306            UtDisplayConstantOpcodes ();
307            exit (0);
308
309        case 'f':
310
311            AslFilenameHelp ();
312            exit (0);
313
314        case 'r':
315
316            /* reserved names */
317
318            ApDisplayReservedNames ();
319            exit (0);
320
321        case 't':
322
323            UtDisplaySupportedTables ();
324            exit (0);
325
326        default:
327
328            printf ("Unknown option: -h%s\n", AcpiGbl_Optarg);
329            return (-1);
330        }
331
332    case 'I':   /* Add an include file search directory */
333
334        FlAddIncludeDirectory (AcpiGbl_Optarg);
335        break;
336
337    case 'i':   /* Output AML as an include file */
338
339        switch (AcpiGbl_Optarg[0])
340        {
341        case 'a':
342
343            /* Produce assembly code include file */
344
345            Gbl_AsmIncludeOutputFlag = TRUE;
346            break;
347
348        case 'c':
349
350            /* Produce C include file */
351
352            Gbl_C_IncludeOutputFlag = TRUE;
353            break;
354
355        case 'n':
356
357            /* Compiler/Disassembler: Ignore the NOOP operator */
358
359            AcpiGbl_IgnoreNoopOperator = TRUE;
360            break;
361
362        default:
363
364            printf ("Unknown option: -i%s\n", AcpiGbl_Optarg);
365            return (-1);
366        }
367        break;
368
369    case 'l':   /* Listing files */
370
371        switch (AcpiGbl_Optarg[0])
372        {
373        case '^':
374
375            /* Produce listing file (Mixed source/aml) */
376
377            Gbl_ListingFlag = TRUE;
378            break;
379
380        case 'i':
381
382            /* Produce preprocessor output file */
383
384            Gbl_PreprocessorOutputFlag = TRUE;
385            break;
386
387        case 'n':
388
389            /* Produce namespace file */
390
391            Gbl_NsOutputFlag = TRUE;
392            break;
393
394        case 's':
395
396            /* Produce combined source file */
397
398            Gbl_SourceOutputFlag = TRUE;
399            break;
400
401        default:
402
403            printf ("Unknown option: -l%s\n", AcpiGbl_Optarg);
404            return (-1);
405        }
406        break;
407
408    case 'm':   /* Set line buffer size */
409
410        Gbl_LineBufferSize = (UINT32) strtoul (AcpiGbl_Optarg, NULL, 0) * 1024;
411        if (Gbl_LineBufferSize < ASL_DEFAULT_LINE_BUFFER_SIZE)
412        {
413            Gbl_LineBufferSize = ASL_DEFAULT_LINE_BUFFER_SIZE;
414        }
415        printf ("Line Buffer Size: %u\n", Gbl_LineBufferSize);
416        break;
417
418    case 'n':   /* Parse only */
419
420        Gbl_ParseOnlyFlag = TRUE;
421        break;
422
423    case 'o':   /* Control compiler AML optimizations */
424
425        switch (AcpiGbl_Optarg[0])
426        {
427        case 'a':
428
429            /* Disable all optimizations */
430
431            Gbl_FoldConstants = FALSE;
432            Gbl_IntegerOptimizationFlag = FALSE;
433            Gbl_ReferenceOptimizationFlag = FALSE;
434            break;
435
436        case 'f':
437
438            /* Disable folding on "normal" expressions */
439
440            Gbl_FoldConstants = FALSE;
441            break;
442
443        case 'i':
444
445            /* Disable integer optimization to constants */
446
447            Gbl_IntegerOptimizationFlag = FALSE;
448            break;
449
450        case 'n':
451
452            /* Disable named reference optimization */
453
454            Gbl_ReferenceOptimizationFlag = FALSE;
455            break;
456
457        case 't':
458
459            /* Display compile time(s) */
460
461            Gbl_CompileTimesFlag = TRUE;
462            break;
463
464        default:
465
466            printf ("Unknown option: -c%s\n", AcpiGbl_Optarg);
467            return (-1);
468        }
469        break;
470
471    case 'P':   /* Preprocessor options */
472
473        switch (AcpiGbl_Optarg[0])
474        {
475        case '^':   /* Proprocess only, emit (.i) file */
476
477            Gbl_PreprocessOnly = TRUE;
478            Gbl_PreprocessorOutputFlag = TRUE;
479            break;
480
481        case 'n':   /* Disable preprocessor */
482
483            Gbl_PreprocessFlag = FALSE;
484            break;
485
486        default:
487
488            printf ("Unknown option: -P%s\n", AcpiGbl_Optarg);
489            return (-1);
490        }
491        break;
492
493    case 'p':   /* Override default AML output filename */
494
495        Gbl_OutputFilenamePrefix = AcpiGbl_Optarg;
496        Gbl_UseDefaultAmlFilename = FALSE;
497        break;
498
499    case 'r':   /* Override revision found in table header */
500
501        Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
502        break;
503
504    case 's':   /* Create AML in a source code file */
505
506        switch (AcpiGbl_Optarg[0])
507        {
508        case 'a':
509
510            /* Produce assembly code output file */
511
512            Gbl_AsmOutputFlag = TRUE;
513            break;
514
515        case 'c':
516
517            /* Produce C hex output file */
518
519            Gbl_C_OutputFlag = TRUE;
520            break;
521
522        case 'o':
523
524            /* Produce AML offset table in C */
525
526            Gbl_C_OffsetTableFlag = TRUE;
527            break;
528
529        default:
530
531            printf ("Unknown option: -s%s\n", AcpiGbl_Optarg);
532            return (-1);
533        }
534        break;
535
536    case 't':   /* Produce hex table output file */
537
538        switch (AcpiGbl_Optarg[0])
539        {
540        case 'a':
541
542            Gbl_HexOutputFlag = HEX_OUTPUT_ASM;
543            break;
544
545        case 'c':
546
547            Gbl_HexOutputFlag = HEX_OUTPUT_C;
548            break;
549
550        case 's':
551
552            Gbl_HexOutputFlag = HEX_OUTPUT_ASL;
553            break;
554
555        default:
556
557            printf ("Unknown option: -t%s\n", AcpiGbl_Optarg);
558            return (-1);
559        }
560        break;
561
562    case 'T':   /* Create a ACPI table template file */
563
564        Gbl_DoTemplates = TRUE;
565        Gbl_TemplateSignature = AcpiGbl_Optarg;
566        break;
567
568    case 'v':   /* Version and verbosity settings */
569
570        switch (AcpiGbl_Optarg[0])
571        {
572        case '^':
573
574            printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
575            exit (0);
576
577        case 'a':
578
579            /* Disable All error/warning messages */
580
581            Gbl_NoErrors = TRUE;
582            break;
583
584        case 'i':
585            /*
586             * Support for integrated development environment(s).
587             *
588             * 1) No compiler signon
589             * 2) Send stderr messages to stdout
590             * 3) Less verbose error messages (single line only for each)
591             * 4) Error/warning messages are formatted appropriately to
592             *    be recognized by MS Visual Studio
593             */
594            Gbl_VerboseErrors = FALSE;
595            Gbl_DoSignon = FALSE;
596            Gbl_Files[ASL_FILE_STDERR].Handle = stdout;
597            break;
598
599        case 'o':
600
601            Gbl_DisplayOptimizations = TRUE;
602            break;
603
604        case 'r':
605
606            Gbl_DisplayRemarks = FALSE;
607            break;
608
609        case 's':
610
611            Gbl_DoSignon = FALSE;
612            break;
613
614        case 't':
615
616            Gbl_VerboseTemplates = TRUE;
617            break;
618
619        case 'w':
620
621            /* Get the required argument */
622
623            if (AcpiGetoptArgument (argc, argv))
624            {
625                return (-1);
626            }
627
628            Status = AslDisableException (AcpiGbl_Optarg);
629            if (ACPI_FAILURE (Status))
630            {
631                return (-1);
632            }
633            break;
634
635        default:
636
637            printf ("Unknown option: -v%s\n", AcpiGbl_Optarg);
638            return (-1);
639        }
640        break;
641
642    case 'w': /* Set warning levels */
643
644        switch (AcpiGbl_Optarg[0])
645        {
646        case '1':
647
648            Gbl_WarningLevel = ASL_WARNING;
649            break;
650
651        case '2':
652
653            Gbl_WarningLevel = ASL_WARNING2;
654            break;
655
656        case '3':
657
658            Gbl_WarningLevel = ASL_WARNING3;
659            break;
660
661        case 'e':
662
663            Gbl_WarningsAsErrors = TRUE;
664            break;
665
666        default:
667
668            printf ("Unknown option: -w%s\n", AcpiGbl_Optarg);
669            return (-1);
670        }
671        break;
672
673    case 'x':   /* Set debug print output level */
674
675        AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16);
676        break;
677
678    case 'z':
679
680        Gbl_UseOriginalCompilerId = TRUE;
681        break;
682
683    default:
684
685        return (-1);
686    }
687
688    return (0);
689}
690
691
692/*******************************************************************************
693 *
694 * FUNCTION:    AslMergeOptionTokens
695 *
696 * PARAMETERS:  InBuffer            - Input containing an option string
697 *              OutBuffer           - Merged output buffer
698 *
699 * RETURN:      None
700 *
701 * DESCRIPTION: Remove all whitespace from an option string.
702 *
703 ******************************************************************************/
704
705static void
706AslMergeOptionTokens (
707    char                    *InBuffer,
708    char                    *OutBuffer)
709{
710    char                    *Token;
711
712
713    *OutBuffer = 0;
714
715    Token = strtok (InBuffer, ASL_TOKEN_SEPARATORS);
716    while (Token)
717    {
718        strcat (OutBuffer, Token);
719        Token = strtok (NULL, ASL_TOKEN_SEPARATORS);
720    }
721}
722
723
724/*******************************************************************************
725 *
726 * FUNCTION:    AslDoResponseFile
727 *
728 * PARAMETERS:  Filename        - Name of the response file
729 *
730 * RETURN:      Status
731 *
732 * DESCRIPTION: Open a response file and process all options within.
733 *
734 ******************************************************************************/
735
736static int
737AslDoResponseFile (
738    char                    *Filename)
739{
740    char                    *argv = StringBuffer2;
741    FILE                    *ResponseFile;
742    int                     OptStatus = 0;
743    int                     Opterr;
744    int                     Optind;
745
746
747    ResponseFile = fopen (Filename, "r");
748    if (!ResponseFile)
749    {
750        printf ("Could not open command file %s, %s\n",
751            Filename, strerror (errno));
752        return (-1);
753    }
754
755    /* Must save the current GetOpt globals */
756
757    Opterr = AcpiGbl_Opterr;
758    Optind = AcpiGbl_Optind;
759
760    /*
761     * Process all lines in the response file. There must be one complete
762     * option per line
763     */
764    while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ResponseFile))
765    {
766        /* Compress all tokens, allowing us to use a single argv entry */
767
768        AslMergeOptionTokens (StringBuffer, StringBuffer2);
769
770        /* Process the option */
771
772        AcpiGbl_Opterr = 0;
773        AcpiGbl_Optind = 0;
774
775        OptStatus = AslDoOptions (1, &argv, TRUE);
776        if (OptStatus)
777        {
778            printf ("Invalid option in command file %s: %s\n",
779                Filename, StringBuffer);
780            break;
781        }
782    }
783
784    /* Restore the GetOpt globals */
785
786    AcpiGbl_Opterr = Opterr;
787    AcpiGbl_Optind = Optind;
788
789    fclose (ResponseFile);
790    return (OptStatus);
791}
792