| /* Top level support for Mac interface to GDB, the GNU debugger. |
| Copyright 1994 Free Software Foundation, Inc. |
| Contributed by Cygnus Support. Written by Stan Shebs. |
| |
| This file is part of GDB. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
| |
| #include "defs.h" |
| |
| #include <readline/readline.h> |
| #include <readline/history.h> |
| |
| #include <Types.h> |
| #include <Resources.h> |
| #include <QuickDraw.h> |
| #include <Fonts.h> |
| #include <Events.h> |
| #include <Windows.h> |
| #include <Menus.h> |
| #include <TextEdit.h> |
| #include <Dialogs.h> |
| #include <Desk.h> |
| #include <ToolUtils.h> |
| #include <Memory.h> |
| #include <SegLoad.h> |
| #include <Files.h> |
| #include <Folders.h> |
| #include <OSUtils.h> |
| #include <OSEvents.h> |
| #include <DiskInit.h> |
| #include <Packages.h> |
| #include <Traps.h> |
| #include <Lists.h> |
| #include <Gestalt.h> |
| #include <PPCToolbox.h> |
| #include <AppleEvents.h> |
| #include <StandardFile.h> |
| #include <Sound.h> |
| |
| #ifdef MPW |
| #define QD(whatever) (qd.##whatever) |
| #define QDPat(whatever) (&(qd.##whatever)) |
| #endif /* MPW */ |
| |
| #ifdef THINK_C |
| #define QD(whatever) (whatever) |
| #endif |
| |
| #define p2c(pstr,cbuf) \ |
| strncpy(cbuf, ((char *) (pstr) + 1), pstr[0]); \ |
| cbuf[pstr[0]] = '\0'; |
| |
| #define pascalify(STR) \ |
| sprintf(tmpbuf, " %s", STR); \ |
| tmpbuf[0] = strlen(STR); |
| |
| #include "gdbcmd.h" |
| #include "call-cmds.h" |
| #include "symtab.h" |
| #include "inferior.h" |
| #include "signals.h" |
| #include "target.h" |
| #include "breakpoint.h" |
| #include "gdbtypes.h" |
| #include "expression.h" |
| #include "language.h" |
| |
| #include "mac-defs.h" |
| |
| int debug_openp = 0; |
| |
| /* This is true if we are running as a standalone application. */ |
| |
| int mac_app; |
| |
| /* This is true if we are using WaitNextEvent. */ |
| |
| int use_wne; |
| |
| /* This is true if we have Color Quickdraw. */ |
| |
| int has_color_qd; |
| |
| /* This is true if we are using Color Quickdraw. */ |
| |
| int use_color_qd; |
| |
| int inbackground; |
| |
| Rect dragrect = { -32000, -32000, 32000, 32000 }; |
| Rect sizerect; |
| |
| int sbarwid = 15; |
| |
| /* Globals for the console window. */ |
| |
| WindowPtr console_window; |
| |
| ControlHandle console_v_scrollbar; |
| |
| Rect console_v_scroll_rect; |
| |
| TEHandle console_text; |
| |
| Rect console_text_rect; |
| |
| /* This will go away eventually. */ |
| gdb_has_a_terminal () { return 1; } |
| |
| mac_init () |
| { |
| SysEnvRec se; |
| int eventloopdone = 0; |
| char *str; |
| Boolean gotevent; |
| Point mouse; |
| EventRecord event; |
| WindowPtr win; |
| RgnHandle cursorRgn; |
| int i; |
| Handle menubar; |
| MenuHandle menu; |
| Handle siow_resource; |
| |
| mac_app = 0; |
| |
| str = getenv("DEBUG_GDB"); |
| if (str != NULL && str[0] != '\0') |
| { |
| if (strcmp(str, "openp") == 0) |
| debug_openp = 1; |
| } |
| |
| /* Don't do anything if we`re running under MPW. */ |
| if (!StandAlone) |
| return; |
| |
| /* Don't do anything if we're using SIOW. */ |
| /* This test requires that the siow 0 resource, as defined in |
| {RIncludes}siow.r, not be messed with. If it is, then the |
| standard Mac setup below will step on SIOW's Mac setup and |
| most likely crash the machine. */ |
| siow_resource = GetResource('siow', 0); |
| if (siow_resource != nil) |
| return; |
| |
| mac_app = 1; |
| |
| /* Do the standard Mac environment setup. */ |
| InitGraf (&QD (thePort)); |
| InitFonts (); |
| FlushEvents (everyEvent, 0); |
| InitWindows (); |
| InitMenus (); |
| TEInit (); |
| InitDialogs (NULL); |
| InitCursor (); |
| |
| /* Color Quickdraw is different from Classic QD. */ |
| SysEnvirons(2, &se); |
| has_color_qd = se.hasColorQD; |
| /* Use it if we got it. */ |
| use_color_qd = has_color_qd; |
| |
| sizerect.top = 50; |
| sizerect.left = 50; |
| sizerect.bottom = 1000; |
| sizerect.right = 1000; |
| #if 0 |
| sizerect.bottom = screenBits.bounds.bottom - screenBits.bounds.top; |
| sizerect.right = screenBits.bounds.right - screenBits.bounds.left; |
| #endif |
| |
| /* Set up the menus. */ |
| menubar = GetNewMBar (mbMain); |
| SetMenuBar (menubar); |
| /* Add the DAs etc as usual. */ |
| menu = GetMHandle (mApple); |
| if (menu != nil) { |
| AddResMenu (menu, 'DRVR'); |
| } |
| DrawMenuBar (); |
| |
| new_console_window (); |
| } |
| |
| new_console_window () |
| { |
| /* Create the main window we're going to play in. */ |
| if (has_color_qd) |
| console_window = GetNewCWindow (wConsole, NULL, (WindowPtr) -1L); |
| else |
| console_window = GetNewWindow (wConsole, NULL, (WindowPtr) -1L); |
| |
| SetPort (console_window); |
| console_text_rect = console_window->portRect; |
| /* Leave 8 pixels of blank space, for aesthetic reasons and to |
| make it easier to select from the beginning of a line. */ |
| console_text_rect.left += 8; |
| console_text_rect.bottom -= sbarwid - 1; |
| console_text_rect.right -= sbarwid - 1; |
| console_text = TENew (&console_text_rect, &console_text_rect); |
| TESetSelect (0, 40000, console_text); |
| TEDelete (console_text); |
| TEAutoView (1, console_text); |
| |
| console_v_scroll_rect = console_window->portRect; |
| console_v_scroll_rect.bottom -= sbarwid - 1; |
| console_v_scroll_rect.left = console_v_scroll_rect.right - sbarwid; |
| console_v_scrollbar = |
| NewControl (console_window, &console_v_scroll_rect, |
| "\p", 1, 0, 0, 0, scrollBarProc, 0L); |
| |
| ShowWindow (console_window); |
| SelectWindow (console_window); |
| } |
| |
| mac_command_loop() |
| { |
| SysEnvRec se; |
| int eventloopdone = 0; |
| Boolean gotevent; |
| Point mouse; |
| EventRecord event; |
| WindowPtr win; |
| RgnHandle cursorRgn; |
| int i, tm; |
| Handle menubar; |
| MenuHandle menu; |
| |
| /* Figure out if the WaitNextEvent Trap is available. */ |
| use_wne = |
| (NGetTrapAddress (0x60, ToolTrap) != NGetTrapAddress (0x9f, ToolTrap)); |
| /* Pass WaitNextEvent an empty region the first time through. */ |
| cursorRgn = NewRgn (); |
| /* Go into the main event-handling loop. */ |
| while (!eventloopdone) |
| { |
| /* Use WaitNextEvent if it is available, otherwise GetNextEvent. */ |
| if (use_wne) |
| { |
| get_global_mouse (&mouse); |
| adjust_cursor (mouse, cursorRgn); |
| tm = GetCaretTime(); |
| gotevent = WaitNextEvent (everyEvent, &event, tm, cursorRgn); |
| } |
| else |
| { |
| SystemTask (); |
| gotevent = GetNextEvent (everyEvent, &event); |
| } |
| /* First decide if the event is for a dialog or is just any old event. */ |
| if (FrontWindow () != nil && IsDialogEvent (&event)) |
| { |
| short itemhit; |
| DialogPtr dialog; |
| |
| /* Handle all the modeless dialogs here. */ |
| if (DialogSelect (&event, &dialog, &itemhit)) |
| { |
| } |
| } |
| else if (gotevent) |
| { |
| /* Make sure we have the right cursor before handling the event. */ |
| adjust_cursor (event.where, cursorRgn); |
| do_event (&event); |
| } |
| else |
| { |
| do_idle (); |
| } |
| } |
| } |
| |
| /* Collect the global coordinates of the mouse pointer. */ |
| |
| get_global_mouse (mouse) |
| Point *mouse; |
| { |
| EventRecord evt; |
| |
| OSEventAvail (0, &evt); |
| *mouse = evt.where; |
| } |
| |
| /* Change the cursor's appearance to be appropriate for the given mouse |
| location. */ |
| |
| adjust_cursor (mouse, region) |
| Point mouse; |
| RgnHandle region; |
| { |
| } |
| |
| /* Decipher an event, maybe do something with it. */ |
| |
| do_event (evt) |
| EventRecord *evt; |
| { |
| short part, err, rslt = 0; |
| WindowPtr win; |
| Boolean hit; |
| char key; |
| Point pnt; |
| |
| switch (evt->what) |
| { |
| case mouseDown: |
| /* See if the click happened in a special part of the screen. */ |
| part = FindWindow (evt->where, &win); |
| switch (part) |
| { |
| case inMenuBar: |
| adjust_menus (); |
| do_menu_command (MenuSelect (evt->where)); |
| break; |
| case inSysWindow: |
| SystemClick (evt, win); |
| break; |
| case inContent: |
| if (win != FrontWindow ()) |
| { |
| /* Bring the clicked-on window to the front. */ |
| SelectWindow (win); |
| /* Fix the menu to match the new front window. */ |
| adjust_menus (); |
| /* We always want to discard the event now, since clicks in a |
| windows are often irreversible actions. */ |
| } else |
| /* Mouse clicks in the front window do something useful. */ |
| do_mouse_down (win, evt); |
| break; |
| case inDrag: |
| /* Standard drag behavior, no tricks necessary. */ |
| DragWindow (win, evt->where, &dragrect); |
| break; |
| case inGrow: |
| grow_window (win, evt->where); |
| break; |
| case inZoomIn: |
| case inZoomOut: |
| zoom_window (win, evt->where, part); |
| break; |
| case inGoAway: |
| close_window (win); |
| break; |
| } |
| break; |
| case keyDown: |
| case autoKey: |
| key = evt->message & charCodeMask; |
| /* Check for menukey equivalents. */ |
| if (evt->modifiers & cmdKey) |
| { |
| if (evt->what == keyDown) |
| { |
| adjust_menus (); |
| do_menu_command (MenuKey (key)); |
| } |
| } |
| else |
| { |
| if (evt->what == keyDown) |
| { |
| /* Random keypress, interpret it. */ |
| do_keyboard_command (key); |
| } |
| } |
| break; |
| case activateEvt: |
| activate_window ((WindowPtr) evt->message, evt->modifiers & activeFlag); |
| break; |
| case updateEvt: |
| update_window ((WindowPtr) evt->message); |
| break; |
| case diskEvt: |
| /* Call DIBadMount in response to a diskEvt, so that the user can format |
| a floppy. (from DTS Sample) */ |
| if (HiWord (evt->message) != noErr) |
| { |
| SetPt (&pnt, 50, 50); |
| err = DIBadMount (pnt, evt->message); |
| } |
| break; |
| case app4Evt: |
| /* Grab only a single byte. */ |
| switch ((evt->message >> 24) & 0xFF) |
| { |
| case 0xfa: |
| break; |
| case 1: |
| inbackground = !(evt->message & 1); |
| activate_window (FrontWindow (), !inbackground); |
| break; |
| } |
| break; |
| case kHighLevelEvent: |
| AEProcessAppleEvent (evt); |
| break; |
| case nullEvent: |
| do_idle (); |
| rslt = 1; |
| break; |
| default: |
| break; |
| } |
| return rslt; |
| } |
| |
| /* Do any idle-time activities. */ |
| |
| do_idle () |
| { |
| TEIdle (console_text); |
| } |
| |
| grow_window (win, where) |
| WindowPtr win; |
| Point where; |
| { |
| long winsize; |
| int h, v; |
| GrafPtr oldport; |
| |
| winsize = GrowWindow (win, where, &sizerect); |
| /* Only do anything if it actually changed size. */ |
| if (winsize != 0) |
| { |
| GetPort (&oldport); |
| SetPort (win); |
| if (win == console_window) |
| { |
| EraseRect (&win->portRect); |
| h = LoWord (winsize); |
| v = HiWord (winsize); |
| SizeWindow (win, h, v, 1); |
| resize_console_window (); |
| } |
| SetPort (oldport); |
| } |
| } |
| |
| zoom_window (win, where, part) |
| WindowPtr win; |
| Point where; |
| short part; |
| { |
| ZoomWindow (win, part, (win == FrontWindow ())); |
| if (win == console_window) |
| { |
| resize_console_window (); |
| } |
| } |
| |
| resize_console_window () |
| { |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| InvalRect (&console_window->portRect); |
| } |
| |
| close_window (win) |
| WindowPtr win; |
| { |
| } |
| |
| pascal void |
| v_scroll_proc (ControlHandle control, short part) |
| { |
| int oldval, amount = 0, newval; |
| int pagesize = ((*console_text)->viewRect.bottom - (*console_text)->viewRect.top) / (*console_text)->lineHeight; |
| if (part) |
| { |
| oldval = GetCtlValue (control); |
| switch (part) |
| { |
| case inUpButton: |
| amount = 1; |
| break; |
| case inDownButton: |
| amount = -1; |
| break; |
| case inPageUp: |
| amount = pagesize; |
| break; |
| case inPageDown: |
| amount = - pagesize; |
| break; |
| default: |
| /* (should freak out) */ |
| break; |
| } |
| SetCtlValue(control, oldval - amount); |
| newval = GetCtlValue (control); |
| amount = oldval - newval; |
| if (amount) |
| TEScroll (0, amount * (*console_text)->lineHeight, console_text); |
| } |
| } |
| |
| do_mouse_down (WindowPtr win, EventRecord *event) |
| { |
| short part, value; |
| Point mouse; |
| ControlHandle control; |
| |
| if (1 /*is_app_window(win)*/) |
| { |
| SetPort (win); |
| mouse = event->where; |
| GlobalToLocal (&mouse); |
| part = FindControl(mouse, win, &control); |
| if (control == console_v_scrollbar) |
| { |
| switch (part) |
| { |
| case inThumb: |
| value = GetCtlValue (control); |
| part = TrackControl (control, mouse, nil); |
| if (part) |
| { |
| value -= GetCtlValue (control); |
| if (value) |
| TEScroll(0, value * (*console_text)->lineHeight, |
| console_text); |
| } |
| break; |
| default: |
| #if 0 /* don't deal with right now */ |
| #if 1 /* universal headers */ |
| value = TrackControl (control, mouse, (ControlActionUPP) v_scroll_proc); |
| #else |
| value = TrackControl (control, mouse, (ProcPtr) v_scroll_proc); |
| #endif |
| #endif |
| break; |
| } |
| } |
| else |
| { |
| TEClick (mouse, 0, console_text); |
| } |
| } |
| } |
| |
| scroll_text (hlines, vlines) |
| int hlines, vlines; |
| { |
| } |
| |
| activate_window (win, activate) |
| WindowPtr win; |
| int activate; |
| { |
| Rect grow_rect; |
| |
| if (win == nil) return; |
| /* It's convenient to make the activated window also be the |
| current GrafPort. */ |
| if (activate) |
| SetPort(win); |
| /* Activate the console window's scrollbar. */ |
| if (win == console_window) |
| { |
| if (activate) |
| { |
| TEActivate (console_text); |
| /* Cause the grow icon to be redrawn at the next update. */ |
| grow_rect = console_window->portRect; |
| grow_rect.top = grow_rect.bottom - sbarwid; |
| grow_rect.left = grow_rect.right - sbarwid; |
| InvalRect (&grow_rect); |
| } |
| else |
| { |
| TEDeactivate (console_text); |
| DrawGrowIcon (console_window); |
| } |
| HiliteControl (console_v_scrollbar, (activate ? 0 : 255)); |
| } |
| } |
| |
| update_window (win) |
| WindowPtr win; |
| { |
| int controls = 1, growbox = 0; |
| GrafPtr oldport; |
| |
| /* Set the updating window to be the current grafport. */ |
| GetPort (&oldport); |
| SetPort (win); |
| /* recalc_depths(); */ |
| BeginUpdate (win); |
| if (win == console_window) |
| { |
| draw_console (); |
| controls = 1; |
| growbox = 1; |
| } |
| if (controls) |
| UpdateControls (win, win->visRgn); |
| if (growbox) |
| DrawGrowIcon (win); |
| EndUpdate (win); |
| SetPort (oldport); |
| } |
| |
| adjust_menus () |
| { |
| } |
| |
| do_menu_command (which) |
| long which; |
| { |
| short menuid, menuitem; |
| short itemHit; |
| Str255 daname; |
| short daRefNum; |
| Boolean handledbyda; |
| WindowPtr win; |
| short ditem; |
| int i; |
| char cmdbuf[300]; |
| |
| cmdbuf[0] = '\0'; |
| menuid = HiWord (which); |
| menuitem = LoWord (which); |
| switch (menuid) |
| { |
| case mApple: |
| switch (menuitem) |
| { |
| case miAbout: |
| Alert (128, nil); |
| break; |
| #if 0 |
| case miHelp: |
| /* (should pop up help info) */ |
| break; |
| #endif |
| default: |
| GetItem (GetMHandle (mApple), menuitem, daname); |
| daRefNum = OpenDeskAcc (daname); |
| } |
| break; |
| case mFile: |
| switch (menuitem) |
| { |
| case miFileNew: |
| if (console_window == FrontWindow ()) |
| { |
| close_window (console_window); |
| } |
| new_console_window (); |
| break; |
| case miFileOpen: |
| SysBeep (20); |
| break; |
| case miFileQuit: |
| ExitToShell (); |
| break; |
| } |
| break; |
| case mEdit: |
| /* handledbyda = SystemEdit(menuitem-1); */ |
| switch (menuitem) |
| { |
| case miEditCut: |
| TECut (console_text); |
| break; |
| case miEditCopy: |
| TECopy (console_text); |
| break; |
| case miEditPaste: |
| TEPaste (console_text); |
| break; |
| case miEditClear: |
| TEDelete (console_text); |
| break; |
| } |
| /* All of these operations need the same postprocessing. */ |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| break; |
| case mDebug: |
| switch (menuitem) |
| { |
| case miDebugTarget: |
| sprintf (cmdbuf, "target %s", "remote"); |
| break; |
| case miDebugRun: |
| sprintf (cmdbuf, "run"); |
| break; |
| case miDebugContinue: |
| sprintf (cmdbuf, "continue"); |
| break; |
| case miDebugStep: |
| sprintf (cmdbuf, "step"); |
| break; |
| case miDebugNext: |
| sprintf (cmdbuf, "next"); |
| break; |
| } |
| break; |
| } |
| HiliteMenu (0); |
| /* Execute a command if one had been given. Do here because a command |
| may longjmp before we get a chance to unhilite the menu. */ |
| if (strlen (cmdbuf) > 0) |
| execute_command (cmdbuf, 0); |
| } |
| |
| char commandbuf[1000]; |
| |
| do_keyboard_command (key) |
| int key; |
| { |
| int startpos, endpos, i, len; |
| char *last_newline; |
| char buf[10], *text_str, *command, *cmd_start; |
| CharsHandle text; |
| |
| if (key == '\015' || key == '\003') |
| { |
| text = TEGetText (console_text); |
| HLock ((Handle) text); |
| text_str = *text; |
| startpos = (*console_text)->selStart; |
| endpos = (*console_text)->selEnd; |
| if (startpos != endpos) |
| { |
| len = endpos - startpos; |
| cmd_start = text_str + startpos; |
| } |
| else |
| { |
| for (i = startpos - 1; i >= 0; --i) |
| if (text_str[i] == '\015') |
| break; |
| last_newline = text_str + i; |
| len = (text_str + startpos) - 1 - last_newline; |
| cmd_start = last_newline + 1; |
| } |
| if (len > 1000) len = 999; |
| if (len < 0) len = 0; |
| strncpy (commandbuf + 1, cmd_start, len); |
| commandbuf[1 + len] = 0; |
| command = commandbuf + 1; |
| HUnlock ((Handle) text); |
| commandbuf[0] = strlen(command); |
| |
| /* Insert a newline and recalculate before doing any command. */ |
| key = '\015'; |
| TEKey (key, console_text); |
| TEInsert (buf, 1, console_text); |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| |
| if (strlen (command) > 0) |
| { |
| execute_command (command, 0); |
| bpstat_do_actions (&stop_bpstat); |
| } |
| } |
| else |
| { |
| /* A self-inserting character. This includes delete. */ |
| TEKey (key, console_text); |
| } |
| } |
| |
| /* Draw all graphical stuff in the console window. */ |
| |
| draw_console () |
| { |
| SetPort (console_window); |
| TEUpdate (&(console_window->portRect), console_text); |
| } |
| |
| /* Cause an update of a given window's entire contents. */ |
| |
| force_update (win) |
| WindowPtr win; |
| { |
| GrafPtr oldport; |
| |
| if (win == nil) return; |
| GetPort (&oldport); |
| SetPort (win); |
| EraseRect (&win->portRect); |
| InvalRect (&win->portRect); |
| SetPort (oldport); |
| } |
| |
| adjust_console_sizes () |
| { |
| Rect tmprect; |
| |
| tmprect = console_window->portRect; |
| /* Move and size the scrollbar. */ |
| MoveControl (console_v_scrollbar, tmprect.right - sbarwid, 0); |
| SizeControl (console_v_scrollbar, sbarwid + 1, tmprect.bottom - sbarwid + 1); |
| /* Move and size the text. */ |
| tmprect.left += 7; |
| tmprect.right -= sbarwid; |
| tmprect.bottom -= sbarwid; |
| InsetRect(&tmprect, 1, 1); |
| (*console_text)->destRect = tmprect; |
| /* Fiddle bottom of viewrect to be even multiple of text lines. */ |
| tmprect.bottom = tmprect.top |
| + ((tmprect.bottom - tmprect.top) / (*console_text)->lineHeight) |
| * (*console_text)->lineHeight; |
| (*console_text)->viewRect = tmprect; |
| } |
| |
| adjust_console_scrollbars () |
| { |
| int lines, newmax, value; |
| |
| (*console_v_scrollbar)->contrlVis = 0; |
| lines = (*console_text)->nLines; |
| newmax = lines - (((*console_text)->viewRect.bottom |
| - (*console_text)->viewRect.top) |
| / (*console_text)->lineHeight); |
| if (newmax < 0) newmax = 0; |
| SetCtlMax (console_v_scrollbar, newmax); |
| value = ((*console_text)->viewRect.top - (*console_text)->destRect.top) |
| / (*console_text)->lineHeight; |
| SetCtlValue (console_v_scrollbar, value); |
| (*console_v_scrollbar)->contrlVis = 0xff; |
| ShowControl (console_v_scrollbar); |
| } |
| |
| /* Scroll the TE record so that it is consistent with the scrollbar(s). */ |
| |
| adjust_console_text () |
| { |
| TEScroll (((*console_text)->viewRect.left |
| - (*console_text)->destRect.left) |
| - 0 /* get h scroll value */, |
| ((((*console_text)->viewRect.top - (*console_text)->destRect.top) |
| / (*console_text)->lineHeight) |
| - GetCtlValue (console_v_scrollbar)) |
| * (*console_text)->lineHeight, |
| console_text); |
| } |
| |
| /* Readline substitute. */ |
| |
| char * |
| readline (char *prrompt) |
| { |
| return gdb_readline (prrompt); |
| } |
| |
| char *rl_completer_word_break_characters; |
| |
| char *rl_completer_quote_characters; |
| |
| int (*rl_completion_entry_function) (); |
| |
| int rl_point; |
| |
| char *rl_line_buffer; |
| |
| char *rl_readline_name; |
| |
| /* History substitute. */ |
| |
| void |
| add_history (char *buf) |
| { |
| } |
| |
| void |
| stifle_history (int n) |
| { |
| } |
| |
| int |
| unstifle_history () |
| { |
| } |
| |
| int |
| read_history (char *name) |
| { |
| } |
| |
| int |
| write_history (char *name) |
| { |
| } |
| |
| int |
| history_expand (char *x, char **y) |
| { |
| } |
| |
| extern HIST_ENTRY * |
| history_get (int xxx) |
| { |
| return NULL; |
| } |
| |
| int history_base; |
| |
| char * |
| filename_completion_function (char *text, char *name) |
| { |
| return "?"; |
| } |
| |
| char * |
| tilde_expand (char *str) |
| { |
| return strsave (str); |
| } |
| |
| /* Modified versions of standard I/O. */ |
| |
| #undef fprintf |
| |
| int |
| hacked_fprintf (FILE *fp, const char *fmt, ...) |
| { |
| int ret; |
| va_list ap; |
| |
| va_start (ap, fmt); |
| if (mac_app && (fp == stdout || fp == stderr)) |
| { |
| char buf[1000]; |
| |
| ret = vsprintf(buf, fmt, ap); |
| TEInsert (buf, strlen(buf), console_text); |
| } |
| else |
| ret = vfprintf (fp, fmt, ap); |
| va_end (ap); |
| return ret; |
| } |
| |
| #undef printf |
| |
| int |
| hacked_printf (const char *fmt, ...) |
| { |
| int ret; |
| va_list ap; |
| |
| va_start (ap, fmt); |
| ret = hacked_vfprintf(stdout, fmt, ap); |
| va_end (ap); |
| return ret; |
| } |
| |
| #undef vfprintf |
| |
| int |
| hacked_vfprintf (FILE *fp, const char *format, va_list args) |
| { |
| if (mac_app && (fp == stdout || fp == stderr)) |
| { |
| char buf[1000]; |
| int ret; |
| |
| ret = vsprintf(buf, format, args); |
| TEInsert (buf, strlen(buf), console_text); |
| if (strchr(buf, '\n')) |
| { |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| } |
| return ret; |
| } |
| else |
| return vfprintf (fp, format, args); |
| } |
| |
| #undef fputs |
| |
| hacked_fputs (const char *s, FILE *fp) |
| { |
| if (mac_app && (fp == stdout || fp == stderr)) |
| { |
| TEInsert (s, strlen(s), console_text); |
| if (strchr(s, '\n')) |
| { |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| } |
| return 0; |
| } |
| else |
| return fputs (s, fp); |
| } |
| |
| #undef fputc |
| |
| hacked_fputc (const char c, FILE *fp) |
| { |
| if (mac_app && (fp == stdout || fp == stderr)) |
| { |
| char buf[1]; |
| |
| buf[0] = c; |
| TEInsert (buf, 1, console_text); |
| if (c == '\n') |
| { |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| } |
| return c; |
| } |
| else |
| return fputc (c, fp); |
| } |
| |
| #undef putc |
| |
| hacked_putc (const char c, FILE *fp) |
| { |
| if (mac_app && (fp == stdout || fp == stderr)) |
| { |
| char buf[1]; |
| |
| buf[0] = c; |
| TEInsert (buf, 1, console_text); |
| if (c == '\n') |
| { |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| } |
| return c; |
| } |
| else |
| return fputc (c, fp); |
| } |
| |
| #undef fflush |
| |
| hacked_fflush (FILE *fp) |
| { |
| if (mac_app && (fp == stdout || fp == stderr)) |
| { |
| adjust_console_sizes (); |
| adjust_console_scrollbars (); |
| adjust_console_text (); |
| return 0; |
| } |
| return fflush (fp); |
| } |
| |
| #undef fgetc |
| |
| hacked_fgetc (FILE *fp) |
| { |
| if (mac_app && (fp == stdin)) |
| { |
| /* Catch any attempts to use this. */ |
| DebugStr("\pShould not be reading from stdin!"); |
| return '\n'; |
| } |
| return fgetc (fp); |
| } |