X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/ec3f2f5367c6f1246d7e311e2293c6e0e83df0bc..1cedb821fd6cdd85a56cca535e840a144d97590c:/Cydia.mm diff --git a/Cydia.mm b/Cydia.mm index b4762a19..ddfe6aa4 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -116,6 +116,14 @@ bool _itv; exit(0); \ } while (false) +static uint64_t profile_; + +#define _timestamp ({ \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + tv.tv_sec * 1000000 + tv.tv_usec; \ +}) + /* Objective-C Handle<> {{{ */ template class _H { @@ -158,6 +166,10 @@ class _H { #define _pooled _H _pool([[NSAutoreleasePool alloc] init], true); +void NSLogPoint(const char *fix, const CGPoint &point) { + NSLog(@"%s(%g,%g)", fix, point.x, point.y); +} + void NSLogRect(const char *fix, const CGRect &rect) { NSLog(@"%s(%g,%g)+(%g,%g)", fix, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); } @@ -249,17 +261,19 @@ extern NSString * const kCAFilterNearest; #define lprintf(args...) fprintf(stderr, args) -#define ForSaurik 1 +#define ForRelease 0 +#define ForSaurik 1 && !ForRelease #define RecycleWebViews 0 +#define AlwaysReload 0 && !ForRelease /* Radix Sort {{{ */ @interface NSMutableArray (Radix) -- (void) radixUsingSelector:(SEL)selector withObject:(id)object; +- (void) radixSortUsingSelector:(SEL)selector withObject:(id)object; @end @implementation NSMutableArray (Radix) -- (void) radixUsingSelector:(SEL)selector withObject:(id)object { +- (void) radixSortUsingSelector:(SEL)selector withObject:(id)object { NSInvocation *invocation([NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:"L12@0:4@8"]]); [invocation setSelector:selector]; [invocation setArgument:&object atIndex:2]; @@ -331,6 +345,34 @@ extern NSString * const kCAFilterNearest; @end /* }}} */ +/* Apple Bug Fixes {{{ */ +@implementation UIWebDocumentView (Cydia) + +- (void) _setScrollerOffset:(CGPoint)offset { + UIScroller *scroller([self _scroller]); + + CGSize size([scroller contentSize]); + CGSize bounds([scroller bounds].size); + + CGPoint max; + max.x = size.width - bounds.width; + max.y = size.height - bounds.height; + + // wtf Apple?! + if (max.x < 0) + max.x = 0; + if (max.y < 0) + max.y = 0; + + offset.x = offset.x < 0 ? 0 : offset.x > max.x ? max.x : offset.x; + offset.y = offset.y < 0 ? 0 : offset.y > max.y ? max.y : offset.y; + + [scroller setOffset:offset]; +} + +@end +/* }}} */ + typedef enum { kUIControlEventMouseDown = 1 << 0, kUIControlEventMouseMovedInside = 1 << 2, // mouse moved inside control target @@ -353,10 +395,7 @@ typedef enum { @implementation NSString (Cydia) + (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length { - char data[length + 1]; - memcpy(data, bytes, length); - data[length] = '\0'; - return [NSString stringWithUTF8String:data]; + return [[[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding] autorelease]; } - (NSComparisonResult) compareByPath:(NSString *)other { @@ -745,6 +784,7 @@ class Status : } virtual void Fetch(pkgAcquire::ItemDesc &item) { + //NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]); [delegate_ setProgressTitle:[NSString stringWithUTF8String:("Downloading " + item.ShortDesc).c_str()]]; } @@ -1108,35 +1148,6 @@ class Progress : @end /* }}} */ /* Package Class {{{ */ -NSString *Scour(const char *field, const char *begin, const char *end) { - size_t i(0), l(strlen(field)); - - for (;;) { - const char *name = begin + i; - const char *colon = name + l; - const char *value = colon + 1; - - if ( - value < end && - *colon == ':' && - strncasecmp(name, field, l) == 0 - ) { - while (value != end && value[0] == ' ') - ++value; - const char *line = std::find(value, end, '\n'); - while (line != value && line[-1] == ' ') - --line; - - return [NSString stringWithUTF8Bytes:value length:(line - value)]; - } else { - begin = std::find(begin, end, '\n'); - if (begin == end) - return nil; - ++begin; - } - } -} - @interface Package : NSObject { pkgCache::PkgIterator iterator_; _transient Database *database_; @@ -1294,7 +1305,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { version_ = [database_ policy]->GetCandidateVer(iterator_); NSString *latest = version_.end() ? nil : [NSString stringWithUTF8String:version_.VerStr()]; - latest_ = [StripVersion(latest) retain]; + latest_ = latest == nil ? nil : [StripVersion(latest) retain]; pkgCache::VerIterator current = iterator_.CurrentVer(); NSString *installed = current.end() ? nil : [NSString stringWithUTF8String:current.VerStr()]; @@ -1315,32 +1326,77 @@ NSString *Scour(const char *field, const char *begin, const char *end) { const char *begin, *end; parser->GetRec(begin, end); - name_ = Scour("name", begin, end); + NSString *website(nil); + NSString *sponsor(nil); + NSString *author(nil); + NSString *tag(nil); + + struct { + const char *name_; + NSString **value_; + } names[] = { + {"name", &name_}, + {"icon", &icon_}, + {"depiction", &depiction_}, + {"homepage", &homepage_}, + {"website", &website}, + {"sponsor", &sponsor}, + {"author", &author}, + {"tag", &tag}, + }; + + while (begin != end) + if (*begin == '\n') { + ++begin; + continue; + } else if (isblank(*begin)) next: { + begin = static_cast(memchr(begin + 1, '\n', end - begin - 1)); + if (begin == NULL) + break; + } else if (const char *colon = static_cast(memchr(begin, ':', end - begin))) { + const char *name(begin); + size_t size(colon - begin); + + begin = static_cast(memchr(begin, '\n', end - begin)); + + { + const char *stop(begin == NULL ? end : begin); + while (stop[-1] == '\r') + --stop; + while (++colon != stop && isblank(*colon)); + + for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) + if (strncasecmp(names[i].name_, name, size) == 0) { + NSString *value([NSString stringWithUTF8Bytes:colon length:(stop - colon)]); + *names[i].value_ = value; + break; + } + } + + if (begin == NULL) + break; + ++begin; + } else goto next; + if (name_ != nil) name_ = [name_ retain]; tagline_ = [[NSString stringWithUTF8String:parser->ShortDesc().c_str()] retain]; - icon_ = Scour("icon", begin, end); if (icon_ != nil) icon_ = [icon_ retain]; - depiction_ = Scour("depiction", begin, end); if (depiction_ != nil) depiction_ = [depiction_ retain]; - homepage_ = Scour("homepage", begin, end); if (homepage_ == nil) - homepage_ = Scour("website", begin, end); + homepage_ = website; if ([homepage_ isEqualToString:depiction_]) homepage_ = nil; if (homepage_ != nil) homepage_ = [homepage_ retain]; - NSString *sponsor = Scour("sponsor", begin, end); if (sponsor != nil) sponsor_ = [[Address addressWithString:sponsor] retain]; - NSString *author = Scour("author", begin, end); if (author != nil) author_ = [[Address addressWithString:author] retain]; - NSString *tags = Scour("tag", begin, end); - if (tags != nil) - tags_ = [[tags componentsSeparatedByString:@", "] retain]; + if (tag != nil) + tags_ = [[tag componentsSeparatedByString:@", "] retain]; } if (tags_ != nil) @@ -1517,10 +1573,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { if (current.end()) return essential && [self essential]; - else { - pkgCache::VerIterator candidate = [database_ policy]->GetCandidateVer(iterator_); - return !candidate.end() && candidate != current; - } + else + return !version_.end() && version_ != current; } - (BOOL) essential { @@ -2049,9 +2103,9 @@ static NSArray *Finishes_; withObject:[NSArray arrayWithObjects:string, id, nil] waitUntilDone:YES ]; - else if (type == "pmstatus") + else if (type == "pmstatus") { [delegate_ setProgressTitle:string]; - else if (type == "pmconffile") + } else if (type == "pmconffile") [delegate_ setConfigurationData:string]; else _assert(false); } else _assert(false); @@ -2247,6 +2301,7 @@ static NSArray *Finishes_; cache_.Close(); + _trace(); if (!cache_.Open(progress_, true)) { std::string error; if (!_error->PopMessage(error)) @@ -2265,6 +2320,7 @@ static NSArray *Finishes_; return; } + _trace(); now_ = [[NSDate date] retain]; @@ -2297,11 +2353,14 @@ static NSArray *Finishes_; } [packages_ removeAllObjects]; + _trace(); + profile_ = 0; for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator) if (Package *package = [Package packageWithIterator:iterator database:self]) [packages_ addObject:package]; - + _trace(); [packages_ sortUsingSelector:@selector(compareByName:)]; + _trace(); } - (void) configure { @@ -2640,9 +2699,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - NSString *context = [sheet context]; + NSString *context([sheet context]); - if ([context isEqualToString:@"remove"]) + if ([context isEqualToString:@"remove"]) { switch (button) { case 1: [self cancel]; @@ -2655,10 +2714,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { default: _assert(false); } - else if ([context isEqualToString:@"unable"]) - [self cancel]; - [sheet dismiss]; + [sheet dismiss]; + } else if ([context isEqualToString:@"unable"]) { + [self cancel]; + [sheet dismiss]; + } else + [super alertSheet:sheet buttonClicked:button]; } - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { @@ -2777,6 +2839,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self cancel]; } +#if !AlwaysReload - (void) _rightButtonClicked { if (essential_ != nil) [essential_ popupAlertAnimated:YES]; @@ -2786,6 +2849,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [delegate_ confirm]; } } +#endif @end /* }}} */ @@ -2998,7 +3062,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - NSString *context = [sheet context]; + NSString *context([sheet context]); + if ([context isEqualToString:@"conffile"]) { FILE *input = [database_ input]; @@ -3014,9 +3079,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { default: _assert(false); } - } - [sheet dismiss]; + [sheet dismiss]; + } } - (void) closeButtonPushed { @@ -3106,9 +3171,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { NSString *plist = [path stringByAppendingPathComponent:@"Info.plist"]; if (NSMutableDictionary *info = [[NSMutableDictionary alloc] initWithContentsOfFile:plist]) { [info autorelease]; - [info setObject:path forKey:@"Path"]; - [info setObject:@"System" forKey:@"ApplicationType"]; - [system addInfoDictionary:info]; + if ([info objectForKey:@"CFBundleIdentifier"] != nil) { + [info setObject:path forKey:@"Path"]; + [info setObject:@"System" forKey:@"ApplicationType"]; + [system addInfoDictionary:info]; + } } } } else goto error; @@ -3284,7 +3351,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) _setProgressTitle:(NSString *)title { - [status_ setText:title]; + NSMutableArray *words([[title componentsSeparatedByString:@" "] mutableCopy]); + for (size_t i(0), e([words count]); i != e; ++i) { + NSString *word([words objectAtIndex:i]); + if (Package *package = [database_ packageWithName:word]) + [words replaceObjectAtIndex:i withObject:[package name]]; + } + + [status_ setText:[words componentsJoinedByString:@" "]]; } - (void) _setProgressPercent:(NSNumber *)percent { @@ -3755,14 +3829,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - int count = [buttons_ count]; - _assert(count != 0); - _assert(button <= count + 1); + NSString *context([sheet context]); - if (count != button - 1) - [self _clickButtonWithName:[buttons_ objectAtIndex:(button - 1)]]; + if ([context isEqualToString:@"modify"]) { + int count = [buttons_ count]; + _assert(count != 0); + _assert(button <= count + 1); - [sheet dismiss]; + if (count != button - 1) + [self _clickButtonWithName:[buttons_ objectAtIndex:(button - 1)]]; + + [sheet dismiss]; + } else + [super alertSheet:sheet buttonClicked:button]; } - (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { @@ -3775,6 +3854,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [super webView:sender didClearWindowObject:window forFrame:frame]; } +#if !AlwaysReload - (void) _rightButtonClicked { /*[super _rightButtonClicked]; return;*/ @@ -3794,10 +3874,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { buttons:buttons defaultButtonIndex:2 delegate:self - context:@"manage" + context:@"modify" ] autorelease]]; } } +#endif - (NSString *) _rightButtonTitle { int count = [buttons_ count]; @@ -4348,8 +4429,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - NSString *context = [sheet context]; - if ([context isEqualToString:@"source"]) + NSString *context([sheet context]); + + if ([context isEqualToString:@"source"]) { switch (button) { case 1: { NSString *href = [[sheet textField] text]; @@ -4379,7 +4461,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _assert(false); } - [sheet dismiss]; + [sheet dismiss]; + } } - (id) initWithBook:(RVBook *)book database:(Database *)database { @@ -4450,11 +4533,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { context:@"source" ] autorelease]; + [sheet setNumberOfRows:1]; + [sheet addTextFieldWithValue:@"http://" label:@""]; UITextInputTraits *traits = [[sheet textField] textInputTraits]; [traits setAutocapitalizationType:0]; - [traits setKeyboardType:3]; + [traits setKeyboardType:UIKeyboardTypeURL]; [traits setAutocorrectionType:1]; [sheet popupAlertAnimated:YES]; @@ -4571,7 +4656,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation HomeView - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - [sheet dismiss]; + NSString *context([sheet context]); + + if ([context isEqualToString:@"about"]) + [sheet dismiss]; + else + [super alertSheet:sheet buttonClicked:button]; } - (void) _leftButtonClicked { @@ -4627,9 +4717,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Settings"; } +#if !AlwaysReload - (NSString *) _rightButtonTitle { return nil; } +#endif @end /* }}} */ @@ -4682,6 +4774,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation BrowserView - (void) dealloc { + if (challenge_ != nil) + [challenge_ release]; + WebView *webview = [webview_ webView]; [webview setFrameLoadDelegate:nil]; [webview setResourceLoadDelegate:nil]; @@ -4895,7 +4990,74 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [book_ pushPage:self]; } -- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { +- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { + NSString *context([sheet context]); + + if ([context isEqualToString:@"challenge"]) { + id sender([challenge_ sender]); + + switch (button) { + case 1: { + NSString *username([[sheet textFieldAtIndex:0] text]); + NSString *password([[sheet textFieldAtIndex:1] text]); + + NSURLCredential *credential([NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]); + + [sender useCredential:credential forAuthenticationChallenge:challenge_]; + } break; + + case 2: + [sender cancelAuthenticationChallenge:challenge_]; + break; + + default: + _assert(false); + } + + [challenge_ release]; + challenge_ = nil; + + [sheet dismiss]; + } +} + +- (void) webView:(WebView *)sender resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)source { + challenge_ = [challenge retain]; + + NSURLProtectionSpace *space([challenge protectionSpace]); + NSString *realm([space realm]); + if (realm == nil) + realm = @""; + + UIActionSheet *sheet = [[[UIActionSheet alloc] + initWithTitle:realm + buttons:[NSArray arrayWithObjects:@"Login", @"Cancel", nil] + defaultButtonIndex:0 + delegate:self + context:@"challenge" + ] autorelease]; + + [sheet setNumberOfRows:1]; + + [sheet addTextFieldWithValue:@"" label:@"username"]; + [sheet addTextFieldWithValue:@"" label:@"password"]; + + UITextField *username([sheet textFieldAtIndex:0]); { + UITextInputTraits *traits([username textInputTraits]); + [traits setAutocapitalizationType:0]; + [traits setAutocorrectionType:1]; + } + + UITextField *password([sheet textFieldAtIndex:1]); { + UITextInputTraits *traits([password textInputTraits]); + [traits setAutocapitalizationType:0]; + [traits setAutocorrectionType:1]; + } + + [sheet popupAlertAnimated:YES]; +} + +- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source { NSURL *url = [request URL]; if ([self getSpecial:url]) return nil; @@ -5070,8 +5232,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [webview_ setZoomsFocusedFormControl:YES]; [webview_ setContentsPosition:7]; [webview_ setEnabledGestures:0xa]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x4]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x7]; + [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeIsZoomRubberBandEnabled]; + [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeUpdatesScroller]; [webview_ setSmoothsFonts:YES]; @@ -5843,7 +6005,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } _trace(); - [packages_ radixUsingSelector:@selector(compareForChanges) withObject:nil]; + [packages_ radixSortUsingSelector:@selector(compareForChanges) withObject:nil]; _trace(); Section *upgradable = [[[Section alloc] initWithName:@"Available Upgrades"] autorelease]; @@ -6306,7 +6468,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { case 1: switch (row) { case 0: { UIPreferencesControlTableCell *cell([[[UIPreferencesControlTableCell alloc] init] autorelease]); - [cell setTitle:@"Changes only shows upgrades to installed packages. This minimizes spam from packagers. Activate this to see upgrades to this package even when it is not installed."]; + [cell setShowSelection:NO]; + [cell setTitle:@"Changes only shows upgrades to installed packages so as to minimize spam from packagers. Activate this to see upgrades to this package even when it is not installed."]; return cell; } @@ -6334,10 +6497,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:kUIControlEventMouseUpInside]; subscribedCell_ = [[UIPreferencesControlTableCell alloc] init]; + [subscribedCell_ setShowSelection:NO]; [subscribedCell_ setTitle:@"Show All Changes"]; [subscribedCell_ setControl:subscribedSwitch_]; ignoredCell_ = [[UIPreferencesControlTableCell alloc] init]; + [ignoredCell_ setShowSelection:NO]; [ignoredCell_ setTitle:@"Ignore Upgrades"]; [ignoredCell_ setControl:ignoredSwitch_]; @@ -6469,7 +6634,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { initWithTitle:[NSString stringWithFormat:@"%d Essential Upgrade%@", count, (count == 1 ? @"" : @"s")] buttons:[NSArray arrayWithObjects: @"Upgrade Essential", - @"Upgrade Everything", + @"Complete Upgrade", @"Ignore (Temporary)", nil] defaultButtonIndex:0 @@ -6488,9 +6653,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [overlay_ addSubview:hud]; [hud show:YES];*/ - _trace(); [database_ reloadData]; - _trace(); size_t changes(0); @@ -6868,7 +7031,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { CGSize keysize = [UIKeyboard defaultSize]; CGRect keyrect = {{0, [overlay_ bounds].size.height}, keysize}; keyboard_ = [[UIKeyboard alloc] initWithFrame:keyrect]; - [[UIKeyboardImpl sharedInstance] setSoundsEnabled:(Sounds_Keyboard_ ? YES : NO)]; + //[[UIKeyboardImpl sharedInstance] setSoundsEnabled:(Sounds_Keyboard_ ? YES : NO)]; [overlay_ addSubview:keyboard_]; if (!bootstrap_) @@ -6892,8 +7055,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - NSString *context = [sheet context]; - if ([context isEqualToString:@"fixhalf"]) + NSString *context([sheet context]); + + if ([context isEqualToString:@"fixhalf"]) { switch (button) { case 1: @synchronized (self) { @@ -6921,7 +7085,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { default: _assert(false); } - else if ([context isEqualToString:@"role"]) { + + [sheet dismiss]; + } else if ([context isEqualToString:@"role"]) { switch (button) { case 1: Role_ = @"User"; break; case 2: Role_ = @"Hacker"; break; @@ -6946,7 +7112,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self updateData]; else [self finish]; - } else if ([context isEqualToString:@"upgrade"]) + + [sheet dismiss]; + } else if ([context isEqualToString:@"upgrade"]) { switch (button) { case 1: @synchronized (self) { @@ -6972,7 +7140,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _assert(false); } - [sheet dismiss]; + [sheet dismiss]; + } } - (void) reorganize { _pooled @@ -7125,7 +7294,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self setIdleTimerDisabled:YES]; hud_ = [self addProgressHUD]; - [hud_ setText:@"Reorganizing\n\nWill Automatically\nRestart When Done"]; + [hud_ setText:@"Reorganizing\n\nWill Automatically\nClose When Done"]; [self setStatusBarShowsProgress:YES]; @@ -7241,7 +7410,29 @@ id Dealloc_(id self, SEL selector) { }*/ int main(int argc, char *argv[]) { _pooled - bootstrap_ = argc > 1 && strcmp(argv[1], "--bootstrap") == 0; + bool substrate(false); + + if (argc != 0) { + char **args(argv); + int arge(1); + + for (int argi(1); argi != argc; ++argi) + if (strcmp(argv[argi], "--") == 0) { + arge = argi; + argv[argi] = argv[0]; + argv += argi; + argc -= argi; + break; + } + + for (int argi(1); argi != arge; ++argi) + if (strcmp(args[argi], "--bootstrap") == 0) + bootstrap_ = true; + else if (strcmp(args[argi], "--substrate") == 0) + substrate = true; + else + fprintf(stderr, "unknown argument: %s\n", args[argi]); + } App_ = [[NSBundle mainBundle] bundlePath]; Home_ = NSHomeDirectory(); @@ -7257,10 +7448,12 @@ int main(int argc, char *argv[]) { _pooled setuid(0); setgid(0); +#if 1 /* XXX: this costs 1.4s of startup performance */ if (unlink("/var/cache/apt/pkgcache.bin") == -1) _assert(errno == ENOENT); if (unlink("/var/cache/apt/srcpkgcache.bin") == -1) _assert(errno == ENOENT); +#endif /*Method alloc = class_getClassMethod([NSObject class], @selector(alloc)); alloc_ = alloc->method_imp; @@ -7326,7 +7519,7 @@ int main(int argc, char *argv[]) { _pooled Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease]; #endif - if (access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0) + if (substrate && access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0) dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL); if (access("/User", F_OK) != 0)