home *** CD-ROM | disk | FTP | other *** search
- /* 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
-