• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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