Remove old and ugly printing functions
[centaur.git] / src / options.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <getopt.h>
5
6 #include "options.h"
7
8
9 static void printUsage(char *progname)
10 {
11   printf("Usage: %s [OPTIONS] <elf-file>\n", progname);
12   printf("\n"
13           "Options:\n"
14           "  -h, --help                     Print this help message\n"
15           "  -o, --output                   Where to write the modified ELF file to\n"
16           "\n"
17 //          "ELF dump:\n"
18 //          "      --print-header             Print ELF header\n"
19 //          "      --print-segments           Print program headers\n"
20 //          "      --print-sections           Print sections\n"
21 //          "\n"
22           "Space insertion:\n"
23           "    off: File offset, not within any structure (headers or sections).\n"
24           "    sz:  A multiple of the maximum alignment of all PHDRs.\n"
25           "\n"
26           "      --expand-nobits off        Expand virtual areas (NOBITS sections and similar PHDRs).\n"
27           "      --insert-before off,sz     Insert spacing at given offset,\n"
28           "                                 mapping everything before it to lower mem addresses.\n"
29           "      --insert-after  off,sz     Insert spacing at given offset,\n"
30           "                                 mapping everything after it to higher mem addresses.\n"
31           "\n"
32           "High-level insertion:\n"
33           "      --reladd        obj.o      Automatically insert object file contents\n"
34           "\n");
35 }
36
37
38
39 void parseOptions(CLIOpts *opts, int argc, char **argv)
40 {
41   char *progname = argv[0];
42   int c;
43   int option_index = 0;
44   char *endptr;
45
46   static struct option long_options[] = {
47     {"help", 0, 0, 'h'},
48     {"output", 1, 0, 'o'},
49     {"print-header", 0, 0, 10001},
50     {"print-segments", 0, 0, 10002},
51     {"print-sections", 0, 0, 10003},
52     {"insert-before", 1, 0, 10004},
53     {"insert-after", 1, 0, 10005},
54     {"expand-nobits", 1, 0, 10006},
55     {"reladd", 1, 0, 10007},
56     {NULL, 0, NULL, 0}
57   };
58
59   while ((c = getopt_long(argc, argv, "e:ho:",
60                           long_options, &option_index)) != -1) {
61     switch (c) {
62       case 'h':
63         printUsage(progname);
64         exit(EXIT_SUCCESS);
65       case 'o':
66         opts->fnOutput = optarg;
67         break;
68       case 10001:
69         opts->printHeader = 1;
70         break;
71       case 10002:
72         opts->printSegments = 1;
73         break;
74       case 10003:
75         opts->printSections = 1;
76         break;
77       case 10004:
78         opts->insertBeforeOffs = strtoul(optarg, &endptr, 0);
79         if (endptr[0] != ',') {
80           goto USAGE;
81         }
82         opts->insertBeforeSz = strtoul(endptr + 1, &endptr, 0);
83         if (endptr[0] != '\0' || opts->insertBeforeSz == 0) {
84           goto USAGE;
85         }
86         break;
87       case 10005:
88         opts->insertAfterOffs = strtoul(optarg, &endptr, 0);
89         if (endptr[0] != ',') {
90           goto USAGE;
91         }
92         opts->insertAfterSz = strtoul(endptr + 1, &endptr, 0);
93         if (endptr[0] != '\0' || opts->insertAfterSz == 0) {
94           goto USAGE;
95         }
96         break;
97       case 10006:
98         opts->expandNobitsOffs = strtoul(optarg, &endptr, 0);
99         if (endptr[0] != '\0' || opts->expandNobitsOffs < 1) {
100           goto USAGE;
101         }
102         break;
103       case 10007:
104         opts->fnReladd = optarg;
105         break;
106       case '?':
107       default:
108         goto USAGE;
109     }
110   }
111
112   while (optind < argc) {
113     if (!opts->fnInput) {
114       opts->fnInput = argv[optind];
115     }
116     optind++;
117   }
118
119   if (!opts->fnInput) {
120     fprintf(stderr, "Error: No input file specified.\n\n");
121     goto USAGE;
122   }
123
124   return;
125
126 USAGE:
127   printUsage(progname);
128   exit(1);
129 }