asloptions.c revision 281687
1/******************************************************************************
2 *
3 * Module Name: asloptions - compiler command line processing
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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:f^gh^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    {
123        printf ("Missing input filename\n");
124        BadCommandLine = TRUE;
125    }
126
127    if (Gbl_DoSignon)
128    {
129        printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
130        if (Gbl_IgnoreErrors)
131        {
132            printf ("Ignoring all errors, forcing AML file generation\n\n");
133        }
134    }
135
136    if (BadCommandLine)
137    {
138        printf ("Use -h option for help information\n");
139        exit (1);
140    }
141
142    return (AcpiGbl_Optind);
143}
144
145
146/*******************************************************************************
147 *
148 * FUNCTION:    AslDoOptions
149 *
150 * PARAMETERS:  argc/argv           - Standard argc/argv
151 *              IsResponseFile      - TRUE if executing a response file.
152 *
153 * RETURN:      Status
154 *
155 * DESCRIPTION: Command line option processing
156 *
157 ******************************************************************************/
158
159static int
160AslDoOptions (
161    int                     argc,
162    char                    **argv,
163    BOOLEAN                 IsResponseFile)
164{
165    ACPI_STATUS             Status;
166    UINT32                  j;
167
168
169    /* Get the command line options */
170
171    while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j)
172    {
173    case '@':   /* Begin a response file */
174
175        if (IsResponseFile)
176        {
177            printf ("Nested command files are not supported\n");
178            return (-1);
179        }
180
181        if (AslDoResponseFile (AcpiGbl_Optarg))
182        {
183            return (-1);
184        }
185        break;
186
187    case 'b':   /* Debug options */
188
189        switch (AcpiGbl_Optarg[0])
190        {
191        case 'f':
192
193            AslCompilerdebug = 1; /* same as yydebug */
194            DtParserdebug = 1;
195            PrParserdebug = 1;
196            Gbl_DebugFlag = TRUE;
197            break;
198
199        case 'p':   /* Prune ASL parse tree */
200
201            /* Get the required argument */
202
203            if (AcpiGetoptArgument (argc, argv))
204            {
205                return (-1);
206            }
207
208            Gbl_PruneParseTree = TRUE;
209            Gbl_PruneDepth = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
210            break;
211
212        case 's':
213
214            Gbl_DebugFlag = TRUE;
215            break;
216
217        case 't':
218
219            /* Get the required argument */
220
221            if (AcpiGetoptArgument (argc, argv))
222            {
223                return (-1);
224            }
225
226            Gbl_PruneType = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
227            break;
228
229        default:
230
231            printf ("Unknown option: -b%s\n", AcpiGbl_Optarg);
232            return (-1);
233        }
234
235        break;
236
237    case 'c':
238
239        switch (AcpiGbl_Optarg[0])
240        {
241        case 'r':
242
243            Gbl_NoResourceChecking = TRUE;
244            break;
245
246        default:
247
248            printf ("Unknown option: -c%s\n", AcpiGbl_Optarg);
249            return (-1);
250        }
251        break;
252
253    case 'd':   /* Disassembler */
254
255        switch (AcpiGbl_Optarg[0])
256        {
257        case '^':
258
259            Gbl_DoCompile = FALSE;
260            break;
261
262        case 'a':
263
264            Gbl_DoCompile = FALSE;
265            Gbl_DisassembleAll = TRUE;
266            break;
267
268        case 'b':   /* Do not convert buffers to resource descriptors */
269
270            AcpiGbl_NoResourceDisassembly = TRUE;
271            break;
272
273        case 'c':
274
275            break;
276
277        case 'f':
278
279            AcpiGbl_ForceAmlDisassembly = TRUE;
280            break;
281
282        case 'l':   /* Use legacy ASL code (not ASL+) for disassembly */
283
284            Gbl_DoCompile = FALSE;
285            AcpiGbl_CstyleDisassembly = FALSE;
286            break;
287
288        default:
289
290            printf ("Unknown option: -d%s\n", AcpiGbl_Optarg);
291            return (-1);
292        }
293
294        Gbl_DisasmFlag = TRUE;
295        break;
296
297    case 'D':   /* Define a symbol */
298
299        PrAddDefine (AcpiGbl_Optarg, NULL, TRUE);
300        break;
301
302    case 'e':   /* External files for disassembler */
303
304        /* Get entire list of external files */
305
306        AcpiGbl_Optind--;
307        argv[AcpiGbl_Optind] = AcpiGbl_Optarg;
308
309        while (argv[AcpiGbl_Optind] &&
310              (argv[AcpiGbl_Optind][0] != '-'))
311        {
312            Status = AcpiDmAddToExternalFileList (argv[AcpiGbl_Optind]);
313            if (ACPI_FAILURE (Status))
314            {
315                printf ("Could not add %s to external list\n", argv[AcpiGbl_Optind]);
316                return (-1);
317            }
318
319            AcpiGbl_Optind++;
320        }
321        break;
322
323    case 'f':
324
325        switch (AcpiGbl_Optarg[0])
326        {
327        case '^':   /* Ignore errors and force creation of aml file */
328
329            Gbl_IgnoreErrors = TRUE;
330            break;
331
332        case 'e':   /* Disassembler: Get external declaration file */
333
334            if (AcpiGetoptArgument (argc, argv))
335            {
336                return (-1);
337            }
338
339            Gbl_ExternalRefFilename = AcpiGbl_Optarg;
340            break;
341
342        default:
343
344            printf ("Unknown option: -f%s\n", AcpiGbl_Optarg);
345            return (-1);
346        }
347        break;
348
349    case 'G':
350
351        Gbl_CompileGeneric = TRUE;
352        break;
353
354    case 'g':   /* Get all ACPI tables */
355
356        printf ("-g option is deprecated, use acpidump utility instead\n");
357        exit (1);
358
359    case 'h':
360
361        switch (AcpiGbl_Optarg[0])
362        {
363        case '^':
364
365            Usage ();
366            exit (0);
367
368        case 'c':
369
370            UtDisplayConstantOpcodes ();
371            exit (0);
372
373        case 'f':
374
375            AslFilenameHelp ();
376            exit (0);
377
378        case 'r':
379
380            /* reserved names */
381
382            ApDisplayReservedNames ();
383            exit (0);
384
385        case 't':
386
387            UtDisplaySupportedTables ();
388            exit (0);
389
390        default:
391
392            printf ("Unknown option: -h%s\n", AcpiGbl_Optarg);
393            return (-1);
394        }
395
396    case 'I':   /* Add an include file search directory */
397
398        FlAddIncludeDirectory (AcpiGbl_Optarg);
399        break;
400
401    case 'i':   /* Output AML as an include file */
402
403        switch (AcpiGbl_Optarg[0])
404        {
405        case 'a':
406
407            /* Produce assembly code include file */
408
409            Gbl_AsmIncludeOutputFlag = TRUE;
410            break;
411
412        case 'c':
413
414            /* Produce C include file */
415
416            Gbl_C_IncludeOutputFlag = TRUE;
417            break;
418
419        case 'n':
420
421            /* Compiler/Disassembler: Ignore the NOOP operator */
422
423            AcpiGbl_IgnoreNoopOperator = TRUE;
424            break;
425
426        default:
427
428            printf ("Unknown option: -i%s\n", AcpiGbl_Optarg);
429            return (-1);
430        }
431        break;
432
433    case 'l':   /* Listing files */
434
435        switch (AcpiGbl_Optarg[0])
436        {
437        case '^':
438
439            /* Produce listing file (Mixed source/aml) */
440
441            Gbl_ListingFlag = TRUE;
442            break;
443
444        case 'i':
445
446            /* Produce preprocessor output file */
447
448            Gbl_PreprocessorOutputFlag = TRUE;
449            break;
450
451        case 'm':
452
453            /* Produce hardware map summary file */
454
455            Gbl_MapfileFlag = TRUE;
456            break;
457
458        case 'n':
459
460            /* Produce namespace file */
461
462            Gbl_NsOutputFlag = TRUE;
463            break;
464
465        case 's':
466
467            /* Produce combined source file */
468
469            Gbl_SourceOutputFlag = TRUE;
470            break;
471
472        default:
473
474            printf ("Unknown option: -l%s\n", AcpiGbl_Optarg);
475            return (-1);
476        }
477        break;
478
479    case 'm':   /* Set line buffer size */
480
481        Gbl_LineBufferSize = (UINT32) strtoul (AcpiGbl_Optarg, NULL, 0) * 1024;
482        if (Gbl_LineBufferSize < ASL_DEFAULT_LINE_BUFFER_SIZE)
483        {
484            Gbl_LineBufferSize = ASL_DEFAULT_LINE_BUFFER_SIZE;
485        }
486        printf ("Line Buffer Size: %u\n", Gbl_LineBufferSize);
487        break;
488
489    case 'n':   /* Parse only */
490
491        Gbl_ParseOnlyFlag = TRUE;
492        break;
493
494    case 'o':   /* Control compiler AML optimizations */
495
496        switch (AcpiGbl_Optarg[0])
497        {
498        case 'a':
499
500            /* Disable all optimizations */
501
502            Gbl_FoldConstants = FALSE;
503            Gbl_IntegerOptimizationFlag = FALSE;
504            Gbl_ReferenceOptimizationFlag = FALSE;
505            break;
506
507        case 'f':
508
509            /* Disable folding on "normal" expressions */
510
511            Gbl_FoldConstants = FALSE;
512            break;
513
514        case 'i':
515
516            /* Disable integer optimization to constants */
517
518            Gbl_IntegerOptimizationFlag = FALSE;
519            break;
520
521        case 'n':
522
523            /* Disable named reference optimization */
524
525            Gbl_ReferenceOptimizationFlag = FALSE;
526            break;
527
528        case 't':
529
530            /* Display compile time(s) */
531
532            Gbl_CompileTimesFlag = TRUE;
533            break;
534
535        default:
536
537            printf ("Unknown option: -c%s\n", AcpiGbl_Optarg);
538            return (-1);
539        }
540        break;
541
542    case 'P':   /* Preprocessor options */
543
544        switch (AcpiGbl_Optarg[0])
545        {
546        case '^':   /* Proprocess only, emit (.i) file */
547
548            Gbl_PreprocessOnly = TRUE;
549            Gbl_PreprocessorOutputFlag = TRUE;
550            break;
551
552        case 'n':   /* Disable preprocessor */
553
554            Gbl_PreprocessFlag = FALSE;
555            break;
556
557        default:
558
559            printf ("Unknown option: -P%s\n", AcpiGbl_Optarg);
560            return (-1);
561        }
562        break;
563
564    case 'p':   /* Override default AML output filename */
565
566        Gbl_OutputFilenamePrefix = AcpiGbl_Optarg;
567        UtConvertBackslashes (Gbl_OutputFilenamePrefix);
568        Gbl_UseDefaultAmlFilename = FALSE;
569        break;
570
571    case 'r':   /* Override revision found in table header */
572
573        Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
574        break;
575
576    case 's':   /* Create AML in a source code file */
577
578        switch (AcpiGbl_Optarg[0])
579        {
580        case 'a':
581
582            /* Produce assembly code output file */
583
584            Gbl_AsmOutputFlag = TRUE;
585            break;
586
587        case 'c':
588
589            /* Produce C hex output file */
590
591            Gbl_C_OutputFlag = TRUE;
592            break;
593
594        case 'o':
595
596            /* Produce AML offset table in C */
597
598            Gbl_C_OffsetTableFlag = TRUE;
599            break;
600
601        default:
602
603            printf ("Unknown option: -s%s\n", AcpiGbl_Optarg);
604            return (-1);
605        }
606        break;
607
608    case 't':   /* Produce hex table output file */
609
610        switch (AcpiGbl_Optarg[0])
611        {
612        case 'a':
613
614            Gbl_HexOutputFlag = HEX_OUTPUT_ASM;
615            break;
616
617        case 'c':
618
619            Gbl_HexOutputFlag = HEX_OUTPUT_C;
620            break;
621
622        case 's':
623
624            Gbl_HexOutputFlag = HEX_OUTPUT_ASL;
625            break;
626
627        default:
628
629            printf ("Unknown option: -t%s\n", AcpiGbl_Optarg);
630            return (-1);
631        }
632        break;
633
634    case 'T':   /* Create a ACPI table template file */
635
636        Gbl_DoTemplates = TRUE;
637        Gbl_TemplateSignature = AcpiGbl_Optarg;
638        break;
639
640    case 'v':   /* Version and verbosity settings */
641
642        switch (AcpiGbl_Optarg[0])
643        {
644        case '^':
645
646            printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
647            exit (0);
648
649        case 'a':
650
651            /* Disable all error/warning/remark messages */
652
653            Gbl_NoErrors = TRUE;
654            break;
655
656        case 'e':
657
658            /* Disable all warning/remark messages (errors only) */
659
660            Gbl_DisplayRemarks = FALSE;
661            Gbl_DisplayWarnings = FALSE;
662            break;
663
664        case 'i':
665            /*
666             * Support for integrated development environment(s).
667             *
668             * 1) No compiler signon
669             * 2) Send stderr messages to stdout
670             * 3) Less verbose error messages (single line only for each)
671             * 4) Error/warning messages are formatted appropriately to
672             *    be recognized by MS Visual Studio
673             */
674            Gbl_VerboseErrors = FALSE;
675            Gbl_DoSignon = FALSE;
676            Gbl_Files[ASL_FILE_STDERR].Handle = stdout;
677            break;
678
679        case 'o':
680
681            Gbl_DisplayOptimizations = TRUE;
682            break;
683
684        case 'r':
685
686            Gbl_DisplayRemarks = FALSE;
687            break;
688
689        case 's':
690
691            Gbl_DoSignon = FALSE;
692            break;
693
694        case 't':
695
696            Gbl_VerboseTemplates = TRUE;
697            break;
698
699        case 'w':
700
701            /* Get the required argument */
702
703            if (AcpiGetoptArgument (argc, argv))
704            {
705                return (-1);
706            }
707
708            Status = AslDisableException (AcpiGbl_Optarg);
709            if (ACPI_FAILURE (Status))
710            {
711                return (-1);
712            }
713            break;
714
715        default:
716
717            printf ("Unknown option: -v%s\n", AcpiGbl_Optarg);
718            return (-1);
719        }
720        break;
721
722    case 'w': /* Set warning levels */
723
724        switch (AcpiGbl_Optarg[0])
725        {
726        case '1':
727
728            Gbl_WarningLevel = ASL_WARNING;
729            break;
730
731        case '2':
732
733            Gbl_WarningLevel = ASL_WARNING2;
734            break;
735
736        case '3':
737
738            Gbl_WarningLevel = ASL_WARNING3;
739            break;
740
741        case 'e':
742
743            Gbl_WarningsAsErrors = TRUE;
744            break;
745
746        default:
747
748            printf ("Unknown option: -w%s\n", AcpiGbl_Optarg);
749            return (-1);
750        }
751        break;
752
753    case 'x':   /* Set debug print output level */
754
755        AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16);
756        break;
757
758    case 'z':
759
760        Gbl_UseOriginalCompilerId = TRUE;
761        break;
762
763    default:
764
765        return (-1);
766    }
767
768    return (0);
769}
770
771
772/*******************************************************************************
773 *
774 * FUNCTION:    AslMergeOptionTokens
775 *
776 * PARAMETERS:  InBuffer            - Input containing an option string
777 *              OutBuffer           - Merged output buffer
778 *
779 * RETURN:      None
780 *
781 * DESCRIPTION: Remove all whitespace from an option string.
782 *
783 ******************************************************************************/
784
785static void
786AslMergeOptionTokens (
787    char                    *InBuffer,
788    char                    *OutBuffer)
789{
790    char                    *Token;
791
792
793    *OutBuffer = 0;
794
795    Token = strtok (InBuffer, ASL_TOKEN_SEPARATORS);
796    while (Token)
797    {
798        strcat (OutBuffer, Token);
799        Token = strtok (NULL, ASL_TOKEN_SEPARATORS);
800    }
801}
802
803
804/*******************************************************************************
805 *
806 * FUNCTION:    AslDoResponseFile
807 *
808 * PARAMETERS:  Filename        - Name of the response file
809 *
810 * RETURN:      Status
811 *
812 * DESCRIPTION: Open a response file and process all options within.
813 *
814 ******************************************************************************/
815
816static int
817AslDoResponseFile (
818    char                    *Filename)
819{
820    char                    *argv = StringBuffer2;
821    FILE                    *ResponseFile;
822    int                     OptStatus = 0;
823    int                     Opterr;
824    int                     Optind;
825
826
827    ResponseFile = fopen (Filename, "r");
828    if (!ResponseFile)
829    {
830        printf ("Could not open command file %s, %s\n",
831            Filename, strerror (errno));
832        return (-1);
833    }
834
835    /* Must save the current GetOpt globals */
836
837    Opterr = AcpiGbl_Opterr;
838    Optind = AcpiGbl_Optind;
839
840    /*
841     * Process all lines in the response file. There must be one complete
842     * option per line
843     */
844    while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ResponseFile))
845    {
846        /* Compress all tokens, allowing us to use a single argv entry */
847
848        AslMergeOptionTokens (StringBuffer, StringBuffer2);
849
850        /* Process the option */
851
852        AcpiGbl_Opterr = 0;
853        AcpiGbl_Optind = 0;
854
855        OptStatus = AslDoOptions (1, &argv, TRUE);
856        if (OptStatus)
857        {
858            printf ("Invalid option in command file %s: %s\n",
859                Filename, StringBuffer);
860            break;
861        }
862    }
863
864    /* Restore the GetOpt globals */
865
866    AcpiGbl_Opterr = Opterr;
867    AcpiGbl_Optind = Optind;
868
869    fclose (ResponseFile);
870    return (OptStatus);
871}
872