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