History

tiny_libmaker: more robust arguments interpretation

- Syntax is now much closer to gnu ar, but still supports whatever was supported before, with the following exceptions (which gnu ar has too): - lib is now mandatory (was optional and defaulted to ar_test.a before). - Path cannot start with '-' (but ./-myfile.o is OK). - Unlike gnu ar, modes are still optional (as before). - Now supports also (like gnu ar): - First argument as options doesn't have to start with '-', later options do. - Now supports mode v (verbose) with same output format as gnu ar. - Any names for lib/objs (were limited to .a/.o - broke cmake on windows). - Now explicitly fail on options which would be destructive for the user. - Now doesn't get confused by options between file arguments. - Still ignores other unknown options - as before. - Now doesn't read out-of-bounds if an option is one char. - As a result, cmake for windows can now use tiny_libmaker as ar, and configure can also detect tiny_libmaker as a valid ar (both couldn't before). Ignoring all options could previously cause to misinterpret the mode in a destructive way, e.g. if the user wanted to do something with an existing archive (such as p - print, or x - extract, etc), then it would instead just delete (re-create) the archive. Modes which can be destructive if ignored now explicitly fail. These include [habdioptxN]. Note that 'h' can be ignored, but this way we also implicitly print the usage for -h/--help. The .a/.o name limitations previously resulted in complete failure on some cases, such as cmake on windows which uses <filename>.obj and <libname>.lib .

Avi Halachmi (:avih) committed 10 years ago

Commit 100f94b1 parent 1ca685f1 file · +54 −34Browse files

Unified · Split

win32/tools/tiny_libmaker.c+54−34
@@ -71,50 +71,69 @@ ArHdr arhdro = { · 70 unmodified lines
7171 ARFMAG
7272 };
7373
74+/* Returns 1 if s contains any of the chars of list, else 0 */
75+int contains_any(const char *s, const char *list) {
76+ const char *l;
77+ for (; *s; s++) {
78+ for (l = list; *l; l++) {
79+ if (*s == *l)
80+ return 1;
81+ }
82+ }
83+ return 0;
84+}
85+
86+int usage(int ret) {
87+ fprintf(stderr, "usage: tiny_libmaker [rcsv] lib file...\n");
88+ fprintf(stderr, "Always creates a new lib. [abdioptxN] are explicitly rejected.\n");
89+ return ret;
90+}
91+
7492 int main(int argc, char **argv)
7593 {
7694 FILE *fi, *fh = NULL, *fo = NULL;
7795 ElfW(Ehdr) *ehdr;
7896 ElfW(Shdr) *shdr;
7997 ElfW(Sym) *sym;
80− int i, fsize, iarg;
98+ int i, fsize, i_lib, i_obj;
8199 char *buf, *shstr, *symtab = NULL, *strtab = NULL;
82100 int symtabsize = 0;//, strtabsize = 0;
83101 char *anames = NULL;
84102 int *afpos = NULL;
85103 int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
86− char afile[260], tfile[260], stmp[20];
104+ char tfile[260], stmp[20];
87105 char *file, *name;
88106 int ret = 2;
107+ char *ops_conflict = "habdioptxN"; // unsupported but destructive if ignored.
108+ int verbose = 0;
89109
90−
91− strcpy(afile, "ar_test.a");
92− iarg = 1;
93−
94− if (argc < 2)
95− {
96− printf("usage: tiny_libmaker [lib] file...\n");
97− return 1;
98− }
99− for (i=1; i<argc; i++) {
100− istrlen = strlen(argv[i]);
101− if (argv[i][istrlen-2] == '.') {
102− if(argv[i][istrlen-1] == 'a')
103− strcpy(afile, argv[i]);
104− else if(argv[i][istrlen-1] == 'o') {
105− iarg = i;
106− break;
107− }
110+ i_lib = 0; i_obj = 0; // will hold the index of the lib and first obj
111+ for (i = 1; i < argc; i++) {
112+ const char *a = argv[i];
113+ if (*a == '-' && strstr(a, "."))
114+ return usage(1); // -x.y is always invalid (same as gnu ar)
115+ if ((*a == '-') || (i == 1 && !strstr(a, "."))) { // options argument
116+ if (contains_any(a, ops_conflict))
117+ return usage(1);
118+ if (strstr(a, "v"))
119+ verbose = 1;
120+ } else { // lib or obj files: don't abort - keep validating all args.
121+ if (!i_lib) // first file is the lib
122+ i_lib = i;
123+ else if (!i_obj) // second file is the first obj
124+ i_obj = i;
108125 }
109126 }
127+ if (!i_obj) // implies also no i_lib
128+ return usage(1);
110129
111− if ((fh = fopen(afile, "wb")) == NULL)
130+ if ((fh = fopen(argv[i_lib], "wb")) == NULL)
112131 {
113− fprintf(stderr, "Can't open file %s \n", afile);
132+ fprintf(stderr, "Can't open file %s \n", argv[i_lib]);
114133 goto the_end;
115134 }
116135
117− sprintf(tfile, "%s.tmp", afile);
136+ sprintf(tfile, "%s.tmp", argv[i_lib]);
118137 if ((fo = fopen(tfile, "wb+")) == NULL)
119138 {
120139 fprintf(stderr, "Can't create temporary file %s\n", tfile);
@@ -125,16 +144,19 @@ int main(int argc, char **argv) · 4 unmodified lines
125144 afpos = realloc(NULL, funcmax * sizeof *afpos); // 250 func
126145 memcpy(&arhdro.ar_mode, "100666", 6);
127146
128− //iarg = 1;
129− while (iarg < argc)
147+ // i_obj = first input object file
148+ while (i_obj < argc)
130149 {
131− if (!strcmp(argv[iarg], "rcs")) {
132− iarg++;
150+ if (*argv[i_obj] == '-') { // by now, all options start with '-'
151+ i_obj++;
133152 continue;
134153 }
135− if ((fi = fopen(argv[iarg], "rb")) == NULL)
154+ if (verbose)
155+ printf("a - %s\n", argv[i_obj]);
156+
157+ if ((fi = fopen(argv[i_obj], "rb")) == NULL)
136158 {
137− fprintf(stderr, "Can't open file %s \n", argv[iarg]);
159+ fprintf(stderr, "Can't open file %s \n", argv[i_obj]);
138160 goto the_end;
139161 }
140162 fseek(fi, 0, SEEK_END);
@@ -144,13 +166,11 @@ int main(int argc, char **argv) · 3 unmodified lines
144166 fread(buf, fsize, 1, fi);
145167 fclose(fi);
146168
147− //printf("%s:\n", argv[iarg]);
148−
149169 // elf header
150170 ehdr = (ElfW(Ehdr) *)buf;
151171 if (ehdr->e_ident[4] != ELFCLASSW)
152172 {
153− fprintf(stderr, "Unsupported Elf Class: %s\n", argv[iarg]);
173+ fprintf(stderr, "Unsupported Elf Class: %s\n", argv[i_obj]);
154174 goto the_end;
155175 }
156176
@@ -202,7 +222,7 @@ int main(int argc, char **argv) · 45 unmodified lines
202222 }
203223 }
204224
205− file = argv[iarg];
225+ file = argv[i_obj];
206226 for (name = strchr(file, 0);
207227 name > file && name[-1] != '/' && name[-1] != '\\';
208228 --name);
@@ -217,7 +237,7 @@ int main(int argc, char **argv) · 8 unmodified lines
217237 fwrite(&arhdro, sizeof(arhdro), 1, fo);
218238 fwrite(buf, fsize, 1, fo);
219239 free(buf);
220− iarg++;
240+ i_obj++;
221241 fpos += (fsize + sizeof(arhdro));
222242 }
223243 hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t