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

Reply via email to