blob: a3445cd9b6e0a0d53357315cb441e25bcf9caaf8 [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 {"verbose", no_argument, 0, 'V'},
14 {"help", no_argument, 0, 'h'},
15 {"print-info", no_argument, 0, 'p'},
16 {"list-needed-libs", no_argument, 0, 'n'},
17 {"lookup", required_argument, 0, 'L'},
18 {0, 0, 0, 0},
19};
20
21/* This array must parallel long_options[] */
22static const char *descriptions[] = {
23 "print verbose output",
24 "print help screen",
25 "for each file, generate a listing of all dependencies that each symbol "
26 "satisfies",
27 "print out a list of needed libraries",
28 "provide a directory for library lookup"
29};
30
31void print_help(void)
32{
33 fprintf(stdout,
34 "invokation:\n"
35 "\tlsd file1 [file2 file3 ... fileN] [-Ldir1 -Ldir2 ... -LdirN] "
36 "[-Vpn]\n"
37 "or\n"
38 "\tlsd -h\n\n");
39 fprintf(stdout, "options:\n");
40 struct option *opt = long_options;
41 const char **desc = descriptions;
42 while (opt->name) {
43 fprintf(stdout, "\t-%c\n"
44 "\t--%-15s: %s\n",
45 opt->val,
46 opt->name,
47 *desc);
48 opt++;
49 desc++;
50 }
51}
52
53int get_options(int argc, char **argv,
54 int *list_needed_libs,
55 int *info,
56 char ***dirs,
57 int *num_dirs,
58 int *verbose)
59{
60 int c;
61
62 ASSERT(list_needed_libs);
63 *list_needed_libs = 0;
64 ASSERT(info);
65 *info = 0;
66 ASSERT(verbose);
67 *verbose = 0;
68 ASSERT(dirs);
69 *dirs = NULL;
70 ASSERT(num_dirs);
71 int size = 0;
72 *num_dirs = 0;
73
74 while (1) {
75 /* getopt_long stores the option index here. */
76 int option_index = 0;
77
78 c = getopt_long (argc, argv,
79 "VhpnL:",
80 long_options,
81 &option_index);
82 /* Detect the end of the options. */
83 if (c == -1) break;
84
85 if (isgraph(c)) {
86 INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)"));
87 }
88
89#define SET_STRING_OPTION(name) do { \
90 ASSERT(optarg); \
91 (*name) = strdup(optarg); \
92} while(0)
93
94 switch (c) {
95 case 0:
96 /* If this option set a flag, do nothing else now. */
97 if (long_options[option_index].flag != 0)
98 break;
99 INFO ("option %s", long_options[option_index].name);
100 if (optarg)
101 INFO (" with arg %s", optarg);
102 INFO ("\n");
103 break;
104 case 'h': print_help(); exit(1); break;
105 case 'V': *verbose = 1; break;
106 case 'p': *info = 1; break;
107 case 'n': *list_needed_libs = 1; break;
108 case 'L':
109 {
110 if (*num_dirs == size) {
111 size += 10;
112 *dirs = (char **)REALLOC(*dirs, size * sizeof(char *));
113 }
114 SET_STRING_OPTION(((*dirs) + *num_dirs));
115 (*num_dirs)++;
116 }
117 break;
118 case '?':
119 /* getopt_long already printed an error message. */
120 break;
121
122#undef SET_STRING_OPTION
123
124 default:
125 FAILIF(1, "Unknown option");
126 }
127 }
128
129 return optind;
130}