Home | History | Annotate | Download | only in lsd
      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 
     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 
     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