blob: c2d5e717606baca65261c31adcb1aad8d7142f27 [file] [log] [blame]
The Android Open Source Project88b60792009-03-03 19:28:42 -08001#include <debug.h>
2#include <cmdline.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <getopt.h>
6#include <string.h>
7#include <ctype.h>
8
9extern char *optarg;
10extern int optind, opterr, optopt;
11
12static struct option long_options[] =
13{
14 {"verbose", no_argument, 0, 'V'},
15 {"quiet", no_argument, 0, 'Q'},
16 {"shady", no_argument, 0, 'S'},
17 {"print", no_argument, 0, 'p'},
18 {"help", no_argument, 0, 'h'},
19 {"outfile", required_argument, 0, 'o'},
20 {"filter", required_argument, 0, 'f'},
21 {"dry", no_argument, 0, 'n'},
22 {"strip", no_argument, 0, 's'},
23 {0, 0, 0, 0},
24};
25
26/* This array must parallel long_options[] */
27static
28const char *descriptions[sizeof(long_options)/sizeof(long_options[0])] = {
29 "print verbose output",
30 "suppress errors and warnings",
31 "patch ABS symbols whose values coincide with section starts and ends",
32 "print the symbol table (if specified, only -V is allowed)",
33 "this help screen",
34 "specify an output file (if not provided, input file is modified)",
35 "specify a symbol-filter file",
36 "dry run (perform all calculations but do not modify the ELF file)",
37 "strip debug sections, if they are present"
38};
39
40void print_help(void)
41{
42 fprintf(stdout,
43 "invokation:\n"
44 "\tsoslim file1 [file2 file3 ... fileN] [-Ldir1 -Ldir2 ... -LdirN] "
45 "[-Vpn]\n"
46 "or\n"
47 "\tsoslim -h\n\n");
48 fprintf(stdout, "options:\n");
49 struct option *opt = long_options;
50 const char **desc = descriptions;
51 while (opt->name) {
52 fprintf(stdout, "\t-%c/--%-15s %s\n",
53 opt->val,
54 opt->name,
55 *desc);
56 opt++;
57 desc++;
58 }
59}
60
61int get_options(int argc, char **argv,
62 char **outfile,
63 char **symsfile,
64 int *print_symtab,
65 int *verbose,
66 int *quiet,
67 int *shady,
68 int *dry_run,
69 int *strip_debug)
70{
71 int c;
72
73 ASSERT(outfile);
74 *outfile = NULL;
75 ASSERT(symsfile);
76 *symsfile = NULL;
77 ASSERT(print_symtab);
78 *print_symtab = 0;
79 ASSERT(verbose);
80 *verbose = 0;
81 ASSERT(quiet);
82 *quiet = 0;
83 ASSERT(shady);
84 *shady = 0;
85 ASSERT(dry_run);
86 *dry_run = 0;
87 ASSERT(strip_debug);
88 *strip_debug = 0;
89
90 while (1) {
91 /* getopt_long stores the option index here. */
92 int option_index = 0;
93
94 c = getopt_long (argc, argv,
95 "QVSphi:o:y:Y:f:ns",
96 long_options,
97 &option_index);
98 /* Detect the end of the options. */
99 if (c == -1) break;
100
101 if (isgraph(c)) {
102 INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)"));
103 }
104
105#define SET_STRING_OPTION(name) do { \
106 ASSERT(optarg); \
107 *name = strdup(optarg); \
108} while(0)
109
110 switch (c) {
111 case 0:
112 /* If this option set a flag, do nothing else now. */
113 if (long_options[option_index].flag != 0)
114 break;
115 INFO ("option %s", long_options[option_index].name);
116 if (optarg)
117 INFO (" with arg %s", optarg);
118 INFO ("\n");
119 break;
120 case 'p': *print_symtab = 1; break;
121 case 'h': print_help(); exit(1); break;
122 case 'V': *verbose = 1; break;
123 case 'Q': *quiet = 1; break;
124 case 'S': *shady = 1; break;
125 case 'n': *dry_run = 1; break;
126 case 's': *strip_debug = 1; break;
127 case 'o': SET_STRING_OPTION(outfile); break;
128 case 'f': SET_STRING_OPTION(symsfile); break;
129 case '?':
130 /* getopt_long already printed an error message. */
131 break;
132
133#undef SET_STRING_OPTION
134
135 default:
136 FAILIF(1, "Unknown option");
137 }
138 }
139
140 return optind;
141}