1 #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
9 extern char *optarg;
10 extern int optind, opterr, optopt;
11
12 static 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[] */
22 static 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
print_help(void)31 void 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
get_options(int argc,char ** argv,int * list_needed_libs,int * info,char *** dirs,int * num_dirs,int * verbose)53 int 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 }
131