This is GdbDisplayController.m in view mode; [Download] [Up]
/* GdbDisplayController.m created by ovidiu on Wed 19-Mar-1997 */ #import <Foundation/NSString.h> #import <Foundation/NSArray.h> #import <AppKit/NSWindow.h> #import <AppKit/NSBrowser.h> #import "GdbDisplayController.h" #import "../Document.h" #import "DebuggerController_Protocol.h" #import "Stack.h" #import "Frame.h" #import "Variable.h" #import "GdbBrowserCell.h" #import "FrameBrowserCell.h" /* Private class used to store an object and a selector */ @interface ObjectSelector : NSObject { id object; SEL selector; } + (ObjectSelector*)newWithObject:(id)anObject selector:(SEL)aSelector; - (void)invokeWithArg:(id)gdbOutput type:(GdbOutputType)outputType; @end @implementation ObjectSelector + (ObjectSelector*)newWithObject:(id)anObject selector:(SEL)aSelector { ObjectSelector* obj = [[self new] autorelease]; obj->object = [anObject retain]; obj->selector = aSelector; return obj; } - (void)dealloc { [object release]; [super dealloc]; } - (void)invokeWithArg:(id)gdbOutput type:(GdbOutputType)outputType { IMP imp = [object methodForSelector:selector]; // NSLog (@"%@ output = %@", NSStringFromSelector (_cmd), gdbOutput); (*((void (*)(id, SEL, id, GdbOutputType))imp)) (object, selector, gdbOutput, outputType); } @end @implementation GdbDisplayController static NSString* stackBrowserFrameName = @"Stack Browser Window"; static NSString* selectionMatrixFrameName = @"Gdb Controller Window"; - init { self = [super init]; stack = [Stack new]; [stack setGdbController:self]; objectsToBeNotified = [NSMutableArray new]; currentFrame = -1; return self; } - (void)awakeFromNib { NSWindow* stackBrowserWindow = [stackBrowser window]; NSWindow* selectionMatrixWindow = [selectionMatrix window]; NSString* frameString; NSLog (@"awakeFromNib"); [stackBrowserWindow setFrameAutosaveName:stackBrowserFrameName]; [selectionMatrixWindow setFrameAutosaveName:selectionMatrixFrameName]; #if 0 frameString = [stackBrowserWindow stringWithSavedFrame]; if (frameString) [[stackBrowser window] setFrameFromString:frameString]; NSLog (@"frame1 = %@", frameString); frameString = [selectionMatrixWindow stringWithSavedFrame]; if (frameString) [[selectionMatrix window] setFrameFromString:frameString]; NSLog (@"frame2 = %@/n", frameString); #endif } - (void)dealloc { [stack release]; [objectsToBeNotified release]; [super dealloc]; } /* GuiDisplayProvider2 protocol methods */ - (oneway void) setDebuggerController:(id)dC { gdbManager = [dC retain]; [gdbManager executeCmd:@"set print repeats 0" withTty:YES withAnnotation:NO catchOutput:NO]; [gdbManager executeCmd:@"set print elements 0" withTty:YES withAnnotation:NO catchOutput:NO]; } - (oneway void) breakpointChanged:(int)bpNum newState:(BreakpointState)state inFile:(NSString *)fileName atLine:(int)lineNumber { // NSLog (@"%@: bkpNum %d, file %@, line %d", // NSStringFromSelector(_cmd), bpNum, fileName, lineNumber); } - (oneway void) frameChanged:(int)newFrame { // NSLog (@"frameChanged: newFrame %d", newFrame); [stackBrowser selectRow:[self browserCellForFrame:newFrame] inColumn:0]; currentFrame = newFrame; } - (void)executeGDBCommand:(NSString*)command annotate:(BOOL)flag notifyObject:object selector:(SEL)selector { [gdbManager executeCmd:command withTty:YES withAnnotation:flag catchOutput:YES]; /* Disable all the buttons until we receive the backtrace result */ [self disableAllButtons]; /* Queue the object and selector. The GDB commands are executed in FIFO order, when GDB sends outputFromGDB:type: the first object in array is dequeued. */ [objectsToBeNotified addObject: [ObjectSelector newWithObject:object selector:selector]]; } - (oneway void) stackChanged:(int)newSize limitReached:(BOOL)maxedOut { // NSLog (@"%@", NSStringFromSelector(_cmd)); [self executeGDBCommand:@"backtrace" annotate:YES notifyObject:stack selector:@selector(createStackFromGdbBacktrace:type:)]; [stackBrowser selectRow:[[stackBrowser matrixInColumn:0] numberOfRows] - 1 inColumn:0]; } - (oneway void) lineChangedForThread:(int) t inFile:(NSString *)f atStartLine:(int)sl toEndLine:(int)el { // NSLog (@"lineChangedForThread: file = %@, line = %d", f, sl); [self selectInFile:f startLine:sl endLine:el]; if (currentFrame >= 0) { [[[stack frames] objectAtIndex:currentFrame] setFilename:f startLine:sl endLine:el]; [stackBrowser selectRow:[self browserCellForFrame:currentFrame] inColumn:0]; } } - (oneway void) inferiorStateChanged:(DebuggerState) newState { #if 0 NSString* states[] = { @"DBG_STATE_NOT_ACTIVE", @"DBG_STATE_ACTIVE", @"DBG_STATE_INFERIOR_LOADED", @"DBG_STATE_INFERIOR_EXITED", @"DBG_STATE_INFERIOR_LOGICALLY_RUNNING", @"DBG_STATE_INFERIOR_RUNNING", @"DBG_STATE_INFERIOR_STOPPED" }; NSLog (@"inferiorStateChanged: %@", states[newState]); #endif debuggerState = newState; [self setButtonsConformingToState:newState]; } - (int)query:(NSString*)queryString { // NSLog (@"%@", NSStringFromSelector (_cmd)); return 0; } - (oneway void) outputFromGDB:(NSString*)output type:(GdbOutputType)outputType { id invoke = [objectsToBeNotified objectAtIndex:0]; [invoke invokeWithArg:output type:outputType]; /* Remove the invocation object when all the output has been received. The message with GDB_OUTPUT_ANNOTATION as argument must be the last message sent by GDB. */ if (outputType == GDB_OUTPUT_ANNOTATION) [objectsToBeNotified removeObjectAtIndex:0]; /* If all the commands sent to GDB have been executed display the state */ if (![objectsToBeNotified count]) [self setButtonsConformingToState:debuggerState]; } /* Our methods */ - (void)display:sender { [[selectionMatrix window] makeKeyAndOrderFront:nil]; } - (void)close { [[selectionMatrix window] orderOut:nil]; [[stackBrowser window] orderOut:nil]; } - (void)setButtonsConformingToState:(DebuggerState)state { switch (state) { case DBG_STATE_NOT_ACTIVE: case DBG_STATE_ACTIVE: [runButton setEnabled:NO]; [stopButton setEnabled:NO]; [quitButton setEnabled:NO]; [execCmdMatrix setEnabled:NO]; [lineMatrix setEnabled:NO]; [selectionMatrix setEnabled:NO]; break; case DBG_STATE_INFERIOR_LOADED: case DBG_STATE_INFERIOR_EXITED: [runButton setEnabled:YES]; [stopButton setEnabled:NO]; [quitButton setEnabled:YES]; [execCmdMatrix setEnabled:NO]; [lineMatrix setEnabled:YES]; [selectionMatrix setEnabled:NO]; break; case DBG_STATE_INFERIOR_STOPPED: case DBG_STATE_INFERIOR_LOGICALLY_RUNNING: [runButton setEnabled:YES]; [stopButton setEnabled:NO]; [quitButton setEnabled:YES]; [execCmdMatrix setEnabled:YES]; [lineMatrix setEnabled:YES]; [selectionMatrix setEnabled:YES]; break; case DBG_STATE_INFERIOR_RUNNING: [runButton setEnabled:NO]; [stopButton setEnabled:YES]; [quitButton setEnabled:NO]; [execCmdMatrix setEnabled:NO]; [lineMatrix setEnabled:NO]; [selectionMatrix setEnabled:NO]; break; } } - (void)disableAllButtons { [self setButtonsConformingToState:DBG_STATE_NOT_ACTIVE]; } /* Outlet methods */ - (void)run:sender { int start = YES; if ((debuggerState == DBG_STATE_INFERIOR_STOPPED || debuggerState == DBG_STATE_INFERIOR_LOGICALLY_RUNNING) && !NSRunAlertPanel (@"Warning", @"Program is running. Do you really " @"want to restart it?", @"Yes", @"No", NULL)) start = NO; if (start) { [gdbManager executeCmd:@"set confirm off" withTty:YES withAnnotation:NO]; [gdbManager executeCmd:@"run" withTty:YES withAnnotation:NO]; [gdbManager executeCmd:@"set confirm on" withTty:YES withAnnotation:NO]; } } - (void)interrupt:sender { [gdbManager interrupt]; } - (void)quit:sender { int quit = YES; if ((debuggerState == DBG_STATE_INFERIOR_STOPPED || debuggerState == DBG_STATE_INFERIOR_LOGICALLY_RUNNING) && !NSRunAlertPanel (@"Warning", @"Program is running. Do you really " @"want to quit?", @"Yes", @"No", NULL)) quit = NO; if (quit) { [gdbManager executeCmd:@"set confirm off" withTty:YES withAnnotation:NO]; [gdbManager executeCmd:@"quit" withTty:YES withAnnotation:NO]; // [[stackBrowser window] saveFrameUsingName:stackBrowserFrameName]; // [[selectionMatrix window] saveFrameUsingName:selectionMatrixFrameName]; [[stackBrowser window] setFrameUsingName:[[stackBrowser window] stringWithSavedFrame]]; [[selectionMatrix window] setFrameUsingName:[[selectionMatrix window] stringWithSavedFrame]]; [[NSUserDefaults standardUserDefaults] synchronize]; NSLog (@"stack frame %@", NSStringFromRect([[stackBrowser window] frame])); NSLog (@"matrix frame %@", NSStringFromRect([[selectionMatrix window] frame])); } } - (void)continue:sender { [gdbManager executeCmd:@"continue" withTty:YES withAnnotation:NO]; } - (void)step:sender { [gdbManager executeCmd:@"step" withTty:YES withAnnotation:NO]; } - (void)finish:sender { [gdbManager executeCmd:@"finish" withTty:YES withAnnotation:NO]; } - (void)next:sender { [gdbManager executeCmd:@"next" withTty:YES withAnnotation:NO]; [self invalidateCurrentFrameVariables]; } - (void)breakAt:sender { Document* document = [Document currentDocument]; int line; NSString* command; [document getStartLine:&line endLine:NULL]; command = [NSString stringWithFormat:@"future-break %@:%d", [[document documentName] lastPathComponent], line]; [gdbManager executeCmd:command withTty:YES withAnnotation:NO]; } - (void)runUntil:sender { Document* document = [Document currentDocument]; int line; NSString* command; [document getStartLine:&line endLine:NULL]; command = [NSString stringWithFormat:@"until %@:%d", [[document documentName] lastPathComponent], line]; [gdbManager executeCmd:command withTty:YES withAnnotation:NO]; } - (void)print:sender { Document* document = [Document currentDocument]; NSString* selection = [document selection]; NSString* command = [NSString stringWithFormat:@"print %@", selection]; [gdbManager executeCmd:command withTty:YES withAnnotation:NO]; } - (void)printIndirect:sender { Document* document = [Document currentDocument]; NSString* selection = [document selection]; NSString* command = [NSString stringWithFormat:@"print *(%@)", selection]; [gdbManager executeCmd:command withTty:YES withAnnotation:NO]; } - (void)showStackFrameWindow:sender { [stackBrowser loadColumnZero]; [[stackBrowser window] makeKeyAndOrderFront:nil]; } /* Browser delegate methods */ - (void)browser:(NSBrowser*)sender createRowsForColumn:(int)column inMatrix:(NSMatrix*)matrix { int i, count = 0; if (column == 0) { NSArray* frames = [stack frames]; Frame* frame; FrameBrowserCell* cell; [matrix setPrototype:[[FrameBrowserCell new] autorelease]]; for (i = 0, count = [[stack frames] count]; i < count; i++) { [matrix addRow]; cell = [matrix cellAtRow:i column:0]; frame = [frames objectAtIndex:[self frameNumberForBrowserCell:i]]; [cell setStringValue:[frame functionName]]; [cell setLeaf:([frame fileName] == nil)]; [cell setFrame:frame]; [cell setTarget:cell]; [cell setAction:@selector(_selectLineInFile:)]; [cell setTag:i]; } } else if (column == 1) { int frameNumber = [self frameNumberForBrowserCell:[sender selectedRowInColumn:0]]; Frame* frame = [[stack frames] objectAtIndex:frameNumber]; id cell; [matrix setPrototype:[[GdbBrowserCell new] autorelease]]; [stack setSelectedFrame:frameNumber]; if ([frame variablesAreValid]) { count = [frame numberOfVariables]; for (i = 0; i < count; i++) { [matrix addRow]; cell = [matrix cellAtRow:i column:0]; [cell setObjectToDisplay:[frame variableAtIndex:i]]; } } else [frame getVariablesFromGDB]; } else if (column > 1) { int frameNumber = [self frameNumberForBrowserCell:[sender selectedRowInColumn:0]]; Frame* frame = [[stack frames] objectAtIndex:frameNumber]; id displayableObject; NSArray* components; int i, count, index; [matrix setPrototype:[[GdbBrowserCell new] autorelease]]; [stack setSelectedFrame:frameNumber]; index = [[sender matrixInColumn:1] selectedRow]; displayableObject = [frame variableAtIndex:index]; /* Determine the indirected variable we must show */ for (i = 2; i < column; i++) { index = [[sender matrixInColumn:i] selectedRow]; displayableObject = [[displayableObject indirectedComponents] objectAtIndex:index]; } /* Now we have the variable we have to display. If its indirected value is known already display them, otherwise issue a query to gdb to get them. */ if ([displayableObject indirectedComponentsAreKnown]) { BOOL displayableObjectIsArray = [[displayableObject value] isKindOfClass:[ArrayValue class]]; id cell; components = [displayableObject indirectedComponents]; count = [components count]; for (i = 0; i < count; i++) { [matrix addRow]; cell = [matrix cellAtRow:i column:0]; [cell setObjectToDisplay:[components objectAtIndex:i]]; [cell setObjectIsArrayComponent:displayableObjectIsArray]; } } else [displayableObject getIndirectedComponentsFromGDB]; } } - (int)frameNumberForBrowserCell:(int)row { return [[stack frames] count] - row - 1; } - (int)browserCellForFrame:(int)frameNumber { return [[stack frames] count] - frameNumber - 1; } /* Changing the appearence of stack browser */ - (void)stackChanged { [stackBrowser loadColumnZero]; } - (void)updateCurrentFrame { [stackBrowser reloadColumn:[stackBrowser lastColumn]]; } /* Other methods */ - (id)gdbManager { return gdbManager; } - (id)stackBrowser { return stackBrowser; } - (void)selectInFile:(NSString*)file startLine:(int)sl endLine:(int)el { Document* document; if ([Document openDocumentWithPath:file encoding:UnknownStringEncoding]) { document = [Document documentForPath:file]; [document selectFromLine:sl toEndLine:el]; [document jumpToSelection:nil]; } } - (void)invalidateCurrentFrameVariables { int selectedRow, frameNumber; if ((selectedRow = [stackBrowser selectedRowInColumn:0]) >= 0) { frameNumber = [self frameNumberForBrowserCell:selectedRow]; [[[stack frames] objectAtIndex:frameNumber] invalidateCurrentVariables]; [self updateCurrentFrame]; } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.