Denys Vlasenko wrote:
On Sat, Jun 23, 2012 at 9:52 PM, Doug Clapp <[email protected]> wrote:
commit c5b01016e622f01dfa9c8c542c0968fe37d4a5f2
Author: Denys Vlasenko <[email protected]>
Date: Fri Jun 15 16:43:26 2012 +0200
unzip: make options parsing more robust on getopt w/o gnu extensions
Also, code shrank:
function old new
delta
static.extn 15 10
-5
packed_usage 29231 29217
-14
unzip_main 2388 2291
-97
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-116)
Total: -116 bytes
After it, only -x will break.
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox
Attached is new source file unzip.c. Following John Spencer's email on June
14, I decided to tackle his suggestion of parsing the command line without
getopt. I think I have succeeded in that. One minor issue is -qq, which is
treated the same as -q. If you want the -qq behavior, use -q -q. If I did it
right, the output from make bloatcheck is:
function old new delta
unzip_main 1564 1925 +361
.rodata 2389 2384 -5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 361/-5) Total: 356
bytes
text data bss dec hex filename
24894 430 44 25368 6318 busybox_old
25274 434 44 25752 6498 busybox_unstripped
In my testing both -d and -x appear to function correctly.
I have made documentation suggestions before, but this is my first code
contribution.
Please send a diff.
Please follow code style of the surrounding code.
Please use tabs consistently.
Try this. I added more comments and tweaked the usage information
slightly, as well as reworking the indentation. If the code style is
still a mismatch, could you be more specific about how it differs?
Doug Clapp
diff --git a/archival/unzip.c b/archival/unzip.c
old mode 100644
new mode 100755
index 046027c..cc40bb2
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -28,6 +28,8 @@
//usage: "\n -o Overwrite"
//usage: "\n -p Print to stdout"
//usage: "\n -q Quiet"
+//usage: "\n -q -q Quieter"
+//usage: "\n -v Verbose list"
//usage: "\n -x FILE Exclude FILEs"
//usage: "\n -d DIR Extract into DIR"
@@ -277,7 +279,6 @@ int unzip_main(int argc, char **argv)
IF_NOT_DESKTOP(const) smallint verbose = 0;
smallint listing = 0;
smallint overwrite = O_PROMPT;
- smallint x_opt_seen;
#if ENABLE_DESKTOP
uint32_t cdf_offset;
#endif
@@ -290,9 +291,12 @@ int unzip_main(int argc, char **argv)
llist_t *zaccept = NULL;
llist_t *zreject = NULL;
char *base_dir = NULL;
- int i, opt;
+ int i;
char key_buf[80];
struct stat stat_buf;
+ int argind=1;
+ int dodash=0;
+ char dash[] = "-";
/* -q, -l and -v: UnZip 5.52 of 28 February 2005, by Info-ZIP:
*
@@ -334,81 +338,86 @@ int unzip_main(int argc, char **argv)
* -------- -------
* 204372 1 file
*/
-
- x_opt_seen = 0;
- /* '-' makes getopt return 1 for non-options */
- while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) {
- switch (opt) {
- case 'd': /* Extract to base directory */
- base_dir = optarg;
- break;
-
- case 'l': /* List */
- listing = 1;
+
+ if (argc < 2) bb_show_usage();
+
+ while (argv[argind][0]==dash[0]){
+ if(!argv[argind][1])
break;
-
- case 'n': /* Never overwrite existing files */
- overwrite = O_NEVER;
- break;
-
- case 'o': /* Always overwrite existing files */
- overwrite = O_ALWAYS;
- break;
-
- case 'p': /* Extract files to stdout and fall through to set
verbosity */
- dst_fd = STDOUT_FILENO;
-
- case 'q': /* Be quiet */
+ if (strchr(argv[argind],'l') != NULL) { /* list */
+ listing = 1;
+ }
+ if (strchr(argv[argind],'n') != NULL) { /* Never overwrite
existing files */
+ overwrite = O_NEVER;
+ }
+ if (strchr(argv[argind],'o') != NULL) { /* Always overwrite
existing files */
+ overwrite = O_ALWAYS;
+ }
+ if (strchr(argv[argind],'p') != NULL) { /* Extract files to
stdout */
+ dst_fd = STDOUT_FILENO;
+ }
+ if (strchr(argv[argind],'q') != NULL) { /* Be quiet */
quiet++;
- break;
-
- case 'v': /* Verbose list */
+ }
+ if (strchr(argv[argind],'v') != NULL) { /* Verbose list */
IF_DESKTOP(verbose++;)
listing = 1;
- break;
-
- case 'x':
- x_opt_seen = 1;
- break;
-
- case 1:
- if (!src_fn) {
- /* The zip file */
- /* +5: space for ".zip" and NUL */
- src_fn = xmalloc(strlen(optarg) + 5);
- strcpy(src_fn, optarg);
- } else if (!x_opt_seen) {
- /* Include files */
- llist_add_to(&zaccept, optarg);
- } else {
- /* Exclude files */
- llist_add_to(&zreject, optarg);
+ }
+ argind++;
+ }
+ if(argc>argind){
+ src_fn = xmalloc(strlen(argv[argind]) + 5);
+ strcpy(src_fn, argv[argind]);
+ argind++;
+ }
+ if(argind<argc){
+ if(strncmp(argv[argind],dash,1)==0) {
+ dodash=1;
+ } else
+ dodash=0;
+ while (dodash==0){
+ llist_add_to(&zaccept, argv[argind]);
+ argind++;
+ if(argind>=argc)
+ break;
+ if (strncmp(argv[argind],dash,1)==0) {
+ dodash=1;
}
- break;
-
- default:
- bb_show_usage();
}
}
-
-#ifndef __GLIBC__
- /*
- * This code is needed for non-GNU getopt
- * which doesn't understand "-" in option string.
- * The -x option won't work properly in this case:
- * "unzip a.zip q -x w e" will be interpreted as
- * "unzip a.zip q w e -x" = "unzip a.zip q w e"
- */
- argv += optind;
- if (argv[0]) {
- /* +5: space for ".zip" and NUL */
- src_fn = xmalloc(strlen(argv[0]) + 5);
- strcpy(src_fn, argv[0]);
- while (*++argv)
- llist_add_to(&zaccept, *argv);
+
+ if(argind<argc) {
+ if(strncmp(argv[argind],"-x",2)==0){ /* Exclude files */
+ argind++;
+ if(argind>=argc){
+ bb_show_usage();
+ }
+ if (strncmp(argv[argind],dash,1)!=0) {
+ dodash=0;
+ }
+ while(dodash==0){
+ llist_add_to(&zreject, argv[argind]);
+ argind++;
+ if(argind>=argc)
+ break;
+ if (strncmp(argv[argind],dash,1)==0) {
+ dodash=1;
+ }
+ }
}
-#endif
-
+}
+ if(argind<argc){
+ if(strncmp(argv[argind],"-d",2)==0){ /* Extract to base
directory */
+ argind++;
+ if(argind>=argc){
+ bb_show_usage();
+ }
+ base_dir = argv[argind];
+ argind++;
+ }
+ }
+ if(argind<argc)
+ bb_show_usage();
if (!src_fn) {
bb_show_usage();
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox