Index: utils/OFZIP.m ================================================================== --- utils/OFZIP.m +++ utils/OFZIP.m @@ -29,15 +29,17 @@ #import "macros.h" #define BUFFER_SIZE 4096 @interface OFZIP: OFObject -- (void)listFilesInArchive: (OFZIPArchive*)archive - verbose: (bool)verbose; +{ + int_fast8_t _override, _outputLevel; +} + +- (void)listFilesInArchive: (OFZIPArchive*)archive; - (void)extractFiles: (OFArray*)files - fromArchive: (OFZIPArchive*)archive - override: (int_fast8_t)override; + fromArchive: (OFZIPArchive*)archive; @end OF_APPLICATION_DELEGATE(OFZIP) static void @@ -46,44 +48,47 @@ [stream writeFormat: @"Usage: %@ -[flnvx] archive.zip [file1 file2 ...]\n", [OFApplication programName]]; if (full) { - [stream writeString: @"\nOptions:\n" - @" -f Force / override files\n" - @" -h Show this help\n" - @" -l List all files in the archive\n" - @" -n Never override files\n" - @" -v Verbose output for file list\n" - @" -x Extract files\n"]; + [stream writeString: + @"\nOptions:\n" + @" -f Force / override files\n" + @" -h Show this help\n" + @" -l List all files in the archive\n" + @" -n Never override files\n" + @" -q Quiet mode (no output, except errors)\n" + @" -v Verbose output for file list\n" + @" -x Extract files\n"]; } [OFApplication terminateWithStatus: status]; } @implementation OFZIP - (void)applicationDidFinishLaunching { OFOptionsParser *optionsParser = - [OFOptionsParser parserWithOptions: @"fhlnvx"]; + [OFOptionsParser parserWithOptions: @"fhlnqvx"]; of_unichar_t option, mode = '\0'; - int_fast8_t override = 0; - bool verbose = false; OFArray *remainingArguments; OFZIPArchive *archive; OFArray *files; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case 'f': - override = 1; + _override = 1; break; case 'n': - override = -1; + _override = -1; break; case 'v': - verbose = true; + _outputLevel = 1; + break; + case 'q': + _outputLevel = -1; break; case 'l': case 'x': if (mode != '\0') help(of_stdout, false, 1); @@ -109,12 +114,11 @@ help(of_stderr, false, 1); archive = [OFZIPArchive archiveWithPath: [remainingArguments firstObject]]; - [self listFilesInArchive: archive - verbose: verbose]; + [self listFilesInArchive: archive]; break; case 'x': if ([remainingArguments count] < 1) help(of_stderr, false, 1); @@ -122,12 +126,11 @@ of_range(1, [remainingArguments count] - 1)]; archive = [OFZIPArchive archiveWithPath: [remainingArguments firstObject]]; [self extractFiles: files - fromArchive: archive - override: override]; + fromArchive: archive]; break; default: help(of_stderr, true, 1); break; } @@ -134,19 +137,18 @@ [OFApplication terminate]; } - (void)listFilesInArchive: (OFZIPArchive*)archive - verbose: (bool)verbose { OFEnumerator *enumerator = [[archive entries] objectEnumerator]; OFZIPArchiveEntry *entry; while ((entry = [enumerator nextObject]) != nil) { void *pool = objc_autoreleasePoolPush(); - if (verbose) { + if (_outputLevel > 0) { OFString *date = [[entry modificationDate] localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; [of_stdout writeFormat: @"%@: %" PRIu64 @" (%" PRIu64 @") bytes; %08X; %@; " @@ -160,11 +162,10 @@ } } - (void)extractFiles: (OFArray*)files fromArchive: (OFZIPArchive*)archive - override: (int_fast8_t)override { OFEnumerator *enumerator = [[archive entries] objectEnumerator]; OFZIPArchiveEntry *entry; bool all = ([files count] == 0); OFMutableSet *missing = [OFMutableSet setWithArray: files]; @@ -190,44 +191,47 @@ if ([outFileName hasPrefix: @"/"]) { #else if ([outFileName hasPrefix: @"/"] || [outFileName containsString: @":"]) { #endif - [of_stdout writeFormat: @"Refusing to extract %@!\n", + [of_stderr writeFormat: @"Refusing to extract %@!\n", fileName]; [OFApplication terminateWithStatus: 1]; } componentEnumerator = [[outFileName pathComponents] objectEnumerator]; while ((component = [componentEnumerator nextObject]) != nil) { if ([component isEqual: OF_PATH_PARENT_DIRECTORY]) { - [of_stdout writeFormat: + [of_stderr writeFormat: @"Refusing to extract %@!\n", fileName]; [OFApplication terminateWithStatus: 1]; } } - [of_stdout writeFormat: @"Extracting %@...", fileName]; + if (_outputLevel > -1) + [of_stdout writeFormat: @"Extracting %@...", fileName]; if ([fileName hasSuffix: @"/"]) { [OFFile createDirectoryAtPath: outFileName createParents: true]; - [of_stdout writeLine: @" done"]; + if (_outputLevel > -1) + [of_stdout writeLine: @" done"]; continue; } directory = [outFileName stringByDeletingLastPathComponent]; if (![OFFile directoryExistsAtPath: directory]) [OFFile createDirectoryAtPath: directory createParents: true]; - if ([OFFile fileExistsAtPath: outFileName] && override != 1) { + if ([OFFile fileExistsAtPath: outFileName] && _override != 1) { OFString *line; - if (override == -1) { - [of_stdout writeLine: @" skipped"]; + if (_override == -1) { + if (_outputLevel > -1) + [of_stdout writeLine: @" skipped"]; continue; } do { [of_stderr writeFormat: @@ -243,13 +247,13 @@ } while (![line isEqual: @"y"] && ![line isEqual: @"n"] && ![line isEqual: @"N"] && ![line isEqual: @"A"]); if ([line isEqual: @"A"]) - override = 1; + _override = 1; else if ([line isEqual: @"N"]) - override = -1; + _override = -1; if ([line isEqual: @"n"] || [line isEqual: @"N"]) { [of_stdout writeFormat: @"Skipping %@...\n", fileName]; continue; @@ -270,20 +274,22 @@ written += length; newPercent = (written == size ? 100 : (int_fast8_t)(written * 100 / size)); - if (percent != newPercent) { + if (_outputLevel > -1 && percent != newPercent) { percent = newPercent; [of_stdout writeFormat: @"\rExtracting %@... %3u%%", fileName, percent]; } } - [of_stdout writeFormat: @"\rExtracting %@... done\n", fileName]; + if (_outputLevel > -1) + [of_stdout writeFormat: @"\rExtracting %@... done\n", + fileName]; objc_autoreleasePoolPop(pool); } if ([missing count] > 0) {