page@swan.ulowell.edu (Bob Page) (10/22/88)
Submitted-by: dillon@cory.berkeley.edu (Matt Dillon) Posting-number: Volume 2, Issue 12 Archive-name: editors/dme131.4of6 # This is a shell archive. Remove anything before this line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # This archive contains the following files: # ./src/menu.c # ./src/mods.c # ./src/rexxbind.asm # ./src/command.c # ./src/cmd3.c # ./src/keyboard.c # if `test ! -d ./src` then mkdir ./src echo "mkdir ./src" fi if `test ! -s ./src/menu.c` then echo "writing ./src/menu.c" cat > ./src/menu.c << '\Rogue\Monster\' /* * MENU.C * * Menu routines... made to take up as little space as possible, and * thus uses many tricks which you should watch out for. */ #include "defs.h" typedef struct { ITEM item; char *com; } XITEM; short Menuoff; short DoMenuoff; MENU *Menu; menu_strip(win) WIN *win; { if (!Menuoff && Menu) { SetMenuStrip(win,Menu); Forbid(); win->Flags &= ~RMBTRAP; Permit(); } } menu_off() { register ED *ed; if (Menuoff == 0) { for (ed = (ED *)DBase.mlh_Head; ed->Node.mln_Succ; ed = (ED *)ed->Node.mln_Succ) { ClearMenuStrip(ed->Win); Forbid(); ed->Win->Flags |= RMBTRAP; Permit(); } } ++Menuoff; } menu_on() { register ED *ed; if (Menu && Menuoff == 1) { fixmenu(); for (ed = (ED *)DBase.mlh_Head; ed->Node.mln_Succ; ed = (ED *)ed->Node.mln_Succ) { SetMenuStrip(ed->Win,Menu); Forbid(); ed->Win->Flags &= ~RMBTRAP; Permit(); } } --Menuoff; } do_menuoff() { menu_off(); ++DoMenuoff; } do_menuon() { if (DoMenuoff) { --DoMenuoff; menu_on(); } } char * menutomacro(str) char *str; { char header[64]; char itembuf[64]; register short i; register char *ptr; register MENU *menu; register ITEM *item; for (i = 0; str[i] && str[i] != '-'; ++i); if (str[i] == '-') { strncpy(header, str, i); header[i] = 0; strcpy(itembuf, str + i + 1); for (menu = Menu; menu; menu = menu->NextMenu) { if (ncstrcmp(header, menu->MenuName) == 0) { for (item = menu->FirstItem; item; item = item->NextItem) { ptr = (char *)((ITEXT *)item->ItemFill)->IText; if (ncstrcmp(itembuf, ptr) == 0) { ptr = ((XITEM *)item)->com; goto done; } } } } } ptr = NULL; done: return(ptr); } char * menu_cmd(im) IMESS *im; { XITEM *item; char *ptr; if (item = (XITEM *)ItemAddress(Menu, im->Code)) return(item->com); return(NULL); } fixmenu() { register MENU *menu; register ITEM *item; register ITEXT *it; register int row, col, maxc, scr; col = 0; for (menu = Menu; menu; menu = menu->NextMenu) { maxc = strlen(menu->MenuName); row = 0; for (item = menu->FirstItem; item; item = item->NextItem) { it = (ITEXT *)item->ItemFill; item->TopEdge = row; scr = strlen(((ITEXT *)item->ItemFill)->IText); if (scr > maxc) maxc = scr; item->Height = 10; row += item->Height; } maxc = (maxc * 8) + 16; for (item = menu->FirstItem; item; item = item->NextItem) item->Width = maxc; menu->Width = maxc; menu->LeftEdge = col; menu->Height = row; col += maxc; } } /* * menuclear * menuadd header item command * menudel header item * menudelhdr header */ do_menuclear() { menu_off(); while (Menu) { av[1] = (ubyte *)Menu->MenuName; do_menudelhdr(); } menu_on(); } do_menuadd() { register MENU *menu, **mpr; register ITEM *item, **ipr; register ITEXT *it; menu_off(); mpr = &Menu; for (menu = *mpr; menu; menu = *mpr) { if (strcmp(av[1], menu->MenuName) == 0) { ipr = &menu->FirstItem; for (item = *ipr; item; item = *ipr) { if (strcmp(av[2], ((ITEXT *)item->ItemFill)->IText) == 0) goto newname; ipr = &item->NextItem; } goto newitem; } mpr = &menu->NextMenu; } newmenu: /* create new menu */ menu = malloc(sizeof(MENU)); bzero(menu, sizeof(MENU)); menu->NextMenu = *mpr; *mpr = menu; menu->Flags = MENUENABLED; menu->MenuName = malloc(strlen(av[1])+1); strcpy(menu->MenuName, av[1]); ipr = &menu->FirstItem; *ipr = NULL; newitem: /* create new item */ it = malloc(sizeof(ITEXT)); bzero(it, sizeof(ITEXT)); it->BackPen = 1; it->DrawMode = JAM2; it->IText = malloc(strlen(av[2])+1); strcpy(it->IText, av[2]); item = malloc(sizeof(XITEM)); bzero(item, sizeof(XITEM)); item->NextItem = *ipr; *ipr = item; item->ItemFill = (APTR)it; item->Flags = ITEMTEXT|ITEMENABLED|HIGHCOMP; newname: /* create new name */ if (((XITEM *)item)->com) free(((XITEM *)item)->com); ((XITEM *)item)->com = malloc(strlen(av[3])+1); strcpy(((XITEM *)item)->com, av[3]); menu_on(); } do_menudelhdr() { register MENU *menu; register MENU **mpr; menu_off(); mpr = &Menu; for (menu = *mpr; menu; menu = *mpr) { if (strcmp(av[1], menu->MenuName) == 0) { if (menu->FirstItem) { while (menu->FirstItem) { av[2] = ((ITEXT *)menu->FirstItem->ItemFill)->IText; if (do_menudel()) break; } break; } *mpr = menu->NextMenu; free(menu->MenuName); free(menu); break; } mpr = &menu->NextMenu; } menu_on(); } do_menudel() { register MENU *menu; register ITEM *item, **ipr; register ITEXT *it; short ret = 0; menu_off(); for (menu = Menu; menu; menu = menu->NextMenu) { if (strcmp(av[1], menu->MenuName) == 0) { ipr = &menu->FirstItem; for (item = *ipr; item; item = *ipr) { it = (ITEXT *)item->ItemFill; if (strcmp(av[2], it->IText) == 0) { *ipr = item->NextItem; free(it->IText); free(it); free(((XITEM *)item)->com); free(item); if (!menu->FirstItem) { do_menudelhdr(); ret = 1; } menu_on(); return(ret); } ipr = &item->NextItem; } } } menu_on(); return(ret); } \Rogue\Monster\ else echo "will not over write ./src/menu.c" fi if [ `wc -c ./src/menu.c | awk '{printf $1}'` -ne 5387 ] then echo `wc -c ./src/menu.c | awk '{print "Got " $1 ", Expected " 5387}'` fi if `test ! -s ./src/mods.c` then echo "writing ./src/mods.c" cat > ./src/mods.c << '\Rogue\Monster\' /* * KTS.C * * Additional DME commands written by Kevin T. Seghetti fixed up and * incorporated by Matt Dillon 17 April 1988. */ #include "defs.h" #define BLOCKDEPTH 5 #define PINGDEPTH 10 static long BSstack[BLOCKDEPTH]; static long BEstack[BLOCKDEPTH]; static ED *Bp[BLOCKDEPTH]; static int CurrDepth = 0; static long PingLine[PINGDEPTH]; static long PingCol[PINGDEPTH]; static ED *PingWin[PINGDEPTH]; void PMAdd() { } void PMRem() { } void PMKill(ep) ED *ep; { register short i, j; for (i = 0; i < PINGDEPTH; ++i) { /* remove ping-pong marks */ if (PingWin[i] == ep) PingWin[i] = NULL; } for (i = j = 0; i < CurrDepth; ++i) { /* remove block marks */ Bp[j] = Bp[i]; if (Bp[i] != ep) ++j; } CurrDepth = j; } do_pushmark() { text_sync(); if (blockok()) { if (CurrDepth == BLOCKDEPTH) { title("pushmark: stack limit reached"); return(-1); } BSstack[CurrDepth] = BSline; BEstack[CurrDepth] = BEline; Bp[CurrDepth] = BEp; ++CurrDepth; text_redrawblock(0); } return(0); } void do_popmark() { text_sync(); if (!CurrDepth) { /* no error message on purpose */ text_redrawblock(0); /* remove any existing block */ return; } text_redrawblock(0); --CurrDepth; BSline = BSstack[CurrDepth]; BEline = BEstack[CurrDepth]; BEp = Bp[CurrDepth]; if (BEp == NULL || BEline >= BEp->Lines) { BEp = NULL; BSline = BEline = -1; } else text_redrawblock(1); } void do_swapmark() { register short i; register long *ptmp; register long tmp; if (do_pushmark() < 0) return; i = CurrDepth - 2; if (i >= 0) { ptmp = PingLine + i; tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp; ptmp = PingCol + i; tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp; ptmp = (long *)PingWin + i; tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp; } do_popmark(); } do_purgemark() { CurrDepth = 0; } void do_ping() { register uword num = atoi(av[1]); if (num >= PINGDEPTH) { title("ping: out of range"); return; } PingLine[num]= Ep->Line; PingCol[num] = Ep->Column; PingWin[num] = Ep; title("Line marked"); } void do_pong() { register uword num = atoi(av[1]); extern IBASE *IntuitionBase; text_sync(); if (num < 0 || num >= PINGDEPTH || !PingWin[num]) { title("pong: range error or nothing marked"); return; } text_cursor(1); text_switch(PingWin[num]->Win); text_cursor(0); if (IntuitionBase->ActiveWindow != Ep->Win) { WindowToFront(Ep->Win); ActivateWindow(Ep->Win); } if ((Ep->Line = PingLine[num]) >= Ep->Lines) { PingLine[num] = Ep->Line = Ep->Lines - 1; } Ep->Column = PingCol[num]; text_load(); text_sync(); } void do_undo() { text_load(); text_redisplaycurrline(); } \Rogue\Monster\ else echo "will not over write ./src/mods.c" fi if [ `wc -c ./src/mods.c | awk '{printf $1}'` -ne 2857 ] then echo `wc -c ./src/mods.c | awk '{print "Got " $1 ", Expected " 2857}'` fi if `test ! -s ./src/rexxbind.asm` then echo "writing ./src/rexxbind.asm" cat > ./src/rexxbind.asm << '\Rogue\Monster\' * === rexxbind.asm ===================================================== * * Copyright (c) 1986, 1987 by William S. Hawes (All Rights Reserved) * * ====================================================================== * "Glue" routines for calling functions in the ARexx Systems Library. * All calls assume that the external _RexxSysBase has been set to the * ARexx SYstems library base by a call to OpenLibrary. INCLUDE "rexx/storage.i" INCLUDE "rexx/rxslib.i" XREF _RexxSysBase * First calling convention: * 1, 2, or 3 parameters in (A0,A1,D0), return value in D0. ; msgptr = CreateRexxMsg(&replyport,&fileext,&hostname) XDEF _CreateRexxMsg _CreateRexxMsg: move.w #_LVOCreateRexxMsg,d1 bra.s CallSeq1 ; DeleteArgstring(argptr) XDEF _DeleteArgstring _DeleteArgstring: move.w #_LVODeleteArgstring,d1 bra.s CallSeq1 ; DeleteRexxMsg(msgptr) XDEF _DeleteRexxMsg _DeleteRexxMsg: move.w #_LVODeleteRexxMsg,d1 bra.s CallSeq1 ; FreePort(&msgport) XDEF _FreePort _FreePort: move.w #_LVOFreePort,d1 bra.s CallSeq1 ; signal = InitPort(&replyport) XDEF _InitPort _InitPort: move.w #_LVOInitPort,d1 bra.s CallSeq1 ; boolean = IsRexxMsg(msgptr) XDEF _IsRexxMsg _IsRexxMsg: move.w #_LVOIsRexxMsg,d1 bra.s CallSeq1 ; Load three arguments into (A0,A1,D0) CallSeq1 movea.l 4(sp),a0 movea.l 8(sp),a1 move.l 12(sp),d0 ; Call the library function CallFunc move.l a6,-(sp) movea.l _RexxSysBase,a6 jsr 0(a6,d1.w) movea.l (sp)+,a6 rts * Second calling convention: 2 parameters in (A0,D0), return value in D0. ; argptr = CreateArgstring(&string,length) XDEF _CreateArgstring _CreateArgstring: moveq #_LVOCreateArgstring,d1 bra.s CallSeq2 ; ClearMem(address,length) XDEF _ClearMem _ClearMem: move.w #_LVOClearMem,d1 bra.s CallSeq2 ; Load two arguments (A0,D0) CallSeq2 movea.l 4(sp),a0 move.l 8(sp),d0 bra CallFunc END \Rogue\Monster\ else echo "will not over write ./src/rexxbind.asm" fi if [ `wc -c ./src/rexxbind.asm | awk '{printf $1}'` -ne 2357 ] then echo `wc -c ./src/rexxbind.asm | awk '{print "Got " $1 ", Expected " 2357}'` fi if `test ! -s ./src/command.c` then echo "writing ./src/command.c" cat > ./src/command.c << '\Rogue\Monster\' /* * COMMAND.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved * * )c single character (typing) * 'c single character (typing) * `string' string of characters w/ embedded `' allowed! * (string) same thing w/ embedded () allowed! * \c override * * name arg arg command name. The arguments are interpreted as strings * for the command. * * $scanf macro insert scanf'd variable * $filename macro insert current file name * * Any string arguments not part of a command are considered to be typed * text. */ #include "defs.h" #include <stdio.h> #if AREXX extern int foundcmd; /* control for implicit ARexx macro invocation */ extern int cmderr; /* global command error flag for do_rexx()'s use */ #endif #define CF_COK 1 /* Can be executed while in command line mode */ #define CF_PAR 2 /* ESCIMM special flag.. save rest of command line */ /* so it can be executed after user entry */ #define CF_ICO 4 /* OK to execute if iconified, else uniconify first*/ extern char *breakout(); typedef struct { char *name; /* command name */ ubyte args; ubyte flags; int (*func)(); /* function */ } COMM; extern int do_map(), do_unmap(), do_up(), do_down(), do_left(), do_right(), do_return(), do_bs(), do_del(), do_esc(), do_downadd(), do_lastcolumn(), do_firstcolumn(),do_edit(), do_tab(), do_backtab(), do_save(), do_saveas(), do_deline(), do_insline(), do_top(), do_bottom(), do_source(), do_firstnb(), do_quit(), do_find(), do_page(), do_savetabs(), do_split(), do_goto(), do_screentop(), do_screenbottom(), do_join(), do_repeat(), do_tabstop(), do_insertmode(), do_block(), do_bdelete(), do_bcopy(), do_bmove(), do_bsave(), do_wleft(), do_wright(), do_remeol(), do_savemap(), do_toggle(), do_if(), do_tlate(), do_bsource(), do_findr(), do_findstr(), do_newwindow(), do_windowparm(),do_resize(), do_margin(), do_wordwrap(), do_reformat(), do_execute(), do_chfilename(),do_scrollup(), do_scrolldown(),do_recall(), do_scanf(), do_iconify(), do_tomouse(), do_refs(), do_arpload(), do_arpsave(), do_arpinsfile(),do_setfont(), do_ignorecase(),do_ctags(), do_addpath(), do_rempath(), do_set(), do_setenv(), do_unset(), do_unsetenv(), do_ipc(), do_cd(); extern int do_menu(), do_menuclear(), do_menuadd(), do_menudel(), do_menudelhdr(), do_menuon(), do_menuoff(); extern int do_null(), do_rx(); extern int do_pushmark(), do_popmark(), do_swapmark(), do_purgemark(), do_ping(), do_pong(), do_undo(); #if AREXX extern int do_rx(), do_rx1(), do_rx2(); #endif /*============================================================================*/ /* * WLEFT/WRIGHT will check command line mode themselves, and thus can * be marked flags=1 even though they can change the line number. * * No more than 255 commands may exist unless you change the type of hindex[] * * Command names MUST be sorted by their first character */ unsigned char hindex[26]; /* alpha hash into table */ /* args flags */ COMM Comm[] = { #ifndef NO_DO2 "addpath", 1, CF_COK, do_addpath, #endif "arpinsfile", 0, 0, do_arpinsfile, "arpload", 0, 0, do_arpload, "arpsave", 0, 0, do_arpsave, "back", 0, CF_COK, do_bs, "backtab", 0, CF_COK, do_backtab, "bcopy", 0, 0, do_bcopy, "bdelete", 0, 0, do_bdelete, "block", 0, 0, do_block, /* checks com name for mode */ "bmove", 0, 0, do_bmove, "bottom", 0, 0, do_bottom, "bs", 0, CF_COK, do_bs, "bsave", 1, CF_COK, do_bsave, "bsource", 0, 0, do_bsource, "cd", 1, CF_COK, do_cd, "chfilename", 1, 0, do_chfilename, #ifndef NO_DO_CTAGS "ctags", 0, CF_ICO, do_ctags, #endif "del", 0, CF_COK, do_del, "deline", 0, 0, do_deline, "down", 0, 0, do_down, "downadd", 0, 0, do_downadd, "esc", 0, CF_COK, do_esc, "escimm", 1, CF_PAR, do_esc, "execute", 1, CF_ICO, do_execute, "find", 1, 0, do_find, /* checks com name for mode */ "findr", 2, 0, do_findr, /* checks com name for mode */ "findstr", 1, CF_COK, do_findstr, /* checks com name for mode */ "first", 0, CF_COK, do_firstcolumn, "firstnb", 0, CF_COK, do_firstnb, "goto", 1, 0, do_goto, "height", 1, CF_COK, do_windowparm, "iconify", 0, CF_ICO, do_iconify, "if", 2, CF_COK, do_if, "ifelse", 3, CF_COK, do_if, "ignorecase", 1, CF_COK, do_ignorecase, "insertmode", 1, CF_COK, do_insertmode, "insfile", 1, 0, do_edit, "insline", 0, 0, do_insline, "ipc", 3, CF_COK, do_ipc, "join", 0, 0, do_join, "last", 0, CF_COK, do_lastcolumn, "left", 0, CF_COK, do_left, "leftedge", 1, CF_COK, do_windowparm, "map", 2, CF_COK, do_map, "margin", 1, CF_COK, do_margin, "menuon", 0, 0, do_menuon, "menuoff", 0, 0, do_menuoff, "menuadd", 3, 0, do_menuadd, "menudel", 2, 0, do_menudel, "menudelhdr", 1, 0, do_menudelhdr, "menuclear", 0, 0, do_menuclear, "newfile", 1, 0, do_edit, /* checks com name for mode */ "newwindow", 0, CF_ICO, do_newwindow, "next", 0, 0, do_find, "nextr", 0, 0, do_findr, "null", 0, CF_COK, do_null, "pagedown", 0, 0, do_page, "pageset", 1, 0, do_page, "pageup", 0, 0, do_page, "ping", 1, CF_ICO, do_ping, "pong", 1, 0, do_pong, "prev", 0, 0, do_find, "prevr", 0, 0, do_findr, "popmark", 0, 0, do_popmark, "purgemark", 0, 0, do_purgemark, "pushmark", 0, 0, do_pushmark, "quit", 0, CF_ICO, do_quit, "recall", 0, CF_COK, do_recall, #ifndef NO_DO_REF "ref", 0, 0, do_refs, #endif "reformat", 0, 0, do_reformat, "remeol", 0, CF_COK, do_remeol, #ifndef NO_DO2 "rempath", 1, CF_COK, do_rempath, #endif "repeat", 2, CF_ICO|CF_COK, do_repeat, "repstr", 1, CF_COK, do_findstr, "resettoggle", 1, CF_COK, do_toggle, "resize", 2, 0, do_resize, "return", 0, CF_COK, do_return, /* special meaning in command line mode */ "right", 0, CF_COK, do_right, #if AREXX "rx", 1, 0, do_rx, /* explicit ARexx macro invocation */ "rx1", 2, 0, do_rx1, /* explicit, with 1 arg to ARexx macro */ "rx2", 3, 0, do_rx2, /* explicit, with 2 args to ARexx macro */ #endif "saveas", 1, CF_ICO|CF_COK, do_saveas, "savemap", 1, CF_ICO|CF_COK, do_savemap, /* checks com name for mode */ "saveold", 0, CF_ICO|CF_COK, do_save, "savesmap", 1, CF_ICO|CF_COK, do_savemap, "savetabs", 1, CF_ICO|CF_COK, do_savetabs, "scanf", 1, CF_COK, do_scanf, "screenbottom", 0, 0, do_screenbottom, "screentop", 0, 0, do_screentop, "scrollup", 0, 0, do_scrollup, "scrolldown", 0, 0, do_scrolldown, "set", 2, CF_ICO|CF_COK, do_set, "setenv", 2, CF_ICO|CF_COK, do_setenv, "setfont", 2, 0, do_setfont, "settoggle", 1, CF_COK, do_toggle, "source", 1, CF_COK, do_source, "split", 0, 0, do_split, "swapmark", 0, 0, do_swapmark, "tab", 0, CF_COK, do_tab, "tabstop", 1, CF_COK, do_tabstop, "tlate", 1, CF_COK, do_tlate, "tmpheight", 1, CF_COK, do_windowparm, "tmpwidth", 1, CF_COK, do_windowparm, "toggle", 1, CF_COK, do_toggle, "tomouse", 0, 0, do_tomouse, "top", 0, 0, do_top, "topedge", 1, CF_COK, do_windowparm, "unblock", 0, 0, do_block, "undo", 0, 0, do_undo, "unmap", 1, CF_ICO|CF_COK, do_unmap, "unset", 1, CF_ICO|CF_COK, do_unset, "unsetenv", 1, CF_ICO|CF_COK, do_unsetenv, "up", 0, 0, do_up, "while", 2, CF_ICO|CF_COK, do_if, "width", 1, CF_COK, do_windowparm, "wleft", 0, CF_COK, do_wleft, "wordwrap", 1, CF_COK, do_wordwrap, "wright", 0, CF_COK, do_wright, NULL, 0, 0, NULL }; init_command() { register short hi; register COMM *comm; hi = sizeof(Comm)/sizeof(Comm[0]) - 2; comm = Comm + hi; while (hi >= 0) { hindex[comm->name[0] - 'a'] = hi; --hi; --comm; } } #define MAXIA 5 do_command(str) char *str; { register char *arg; char *aux1, *aux2; char *repstr[MAXIA]; char quoted; short repi = 0; register short i, j; static int level; if (++level > 20) { title("Recursion Too Deep!"); --level; #if AREXX foundcmd = 1; /* to prevent us from trying an ARexx macro */ #endif return(0); } while (arg = breakout(&str, "ed, &aux1)) { if (quoted) { if (Ep->iconmode) uniconify(); text_write(arg); goto loop; } for (i = 0; arg[i]; ++i) { if (arg[i] >= 'A' && arg[i] <= 'Z') arg[i] += 'a' - 'A'; } if (arg[0] >= 'a' && arg[0] <= 'z') { register COMM *comm = &Comm[hindex[arg[0]-'a']]; for (; comm->name && comm->name[0] == arg[0]; ++comm) { if (strcmp(arg, comm->name) == 0) { #if AREXX foundcmd = 1; #endif av[0] = (ubyte *)comm->name; for (j = 1; j <= comm->args; ++j) { av[j] = (ubyte *)breakout(&str, "ed, &aux2); if (aux2) { if (repi == MAXIA) { free(aux2); title("Command too complex"); goto fail; } else { repstr[repi++] = aux2; } } if (!av[j]) { title("Bad argument"); goto fail; } } av[j] = NULL; /* end of arglist */ if ((comm->flags & CF_COK) || !Comlinemode) { if (comm->flags & CF_PAR) { if (Partial) free(Partial); Partial = (char *)malloc(strlen(str)+1); strcpy(Partial, str); str += strlen(str); /* skip string */ } if (Ep->iconmode && !(comm->flags & CF_ICO)) uniconify(); (*comm->func)(-1); } if (Abortcommand) goto fail; goto loop; } } } /* Command not found, check for macro */ { char *str; int ret; if ((str = keyspectomacro(arg)) || (str = menutomacro(arg))) { str = (char *)strcpy(malloc(strlen(str)+1), str); ret = do_command(str); free(str); #if AREXX if (ret) { foundcmd = 1; /* dunno about this yet for ARexx macros */ goto loop; } #else if (ret) goto loop; #endif goto fail; } } /* Command still not found, check for public macro */ /* code to be added */ #if AREXX do_rxImplied(arg, str); #else title("Unknown Command"); #endif fail: --level; while (--repi >= 0) free(repstr[repi]); if (aux1) free(aux1); return(0); loop: if (aux1) free(aux1); } --level; while (--repi >= 0) free(repstr[repi]); return(1); } do_null() { } do_source() { char buf[256]; long xfi; register char *str; long oldlock = CurrentDir(DupLock(Ep->dirlock)); if (xfi = xfopen(av[1], "r", 512)) { while (xfgets(xfi, buf, 256) >= 0) { if (buf[0] == '#') continue; for (str = buf; *str; ++str) { if (*str == 9) *str = ' '; } do_command(buf); } xfclose(xfi); } else { if (av[0]) title("File not found"); } UnLock(CurrentDir(oldlock)); } do_quit() { extern char Quitflag; Quitflag = 1; } do_execute() { long oldlock = CurrentDir(Ep->dirlock); Execute(av[1], NULL, NULL); CurrentDir(oldlock); } /* * repeat X command * * Since repeat takes up 512+ stack, it should not be nested more than * twice. * * (if X is not a number it can be abbr. with 2 chars) * * X = N -number of repeats * line -current line # (lines begin at 1) * lbot -#lines to the bottom, inc. current * cleft -column # (columns begin at 0) * (thus is also chars to the left) * cright-#chars to eol, including current char * tr -#char positions to get to next tab stop * tl -#char positions to get to next backtab stop */ #define SC(a,b) ((a)<<8|(b)) do_repeat() { register ubyte *ptr = av[1]; register unsigned long n; char buf1[256]; char buf2[256]; breakreset(); strcpy(buf1, av[2]); switch((ptr[0]<<8)+ptr[1]) { case SC('l','i'): n = text_lineno(); break; case SC('l','b'): n = text_lines() - text_lineno() + 1; break; case SC('c','l'): n = text_colno(); break; case SC('c','r'): n = text_cols() - text_colno(); break; case SC('t','r'): n = text_tabsize()-(text_colno() % text_tabsize()); break; case SC('t','l'): n = text_colno() % text_tabsize(); if (n == 0) n = text_tabsize(); break; default: n = atoi(av[1]); break; } while (n > 0) { strcpy(buf2, buf1); if (do_command(buf2) == 0 || breakcheck()) { Abortcommand = 1; break; } --n; } } /* * BREAKOUT() * * Break out the next argument. The argument is space delimited and * might be quoted with `' or (), or single quoted as 'c or )c * * Also: $var -variable insertion * ^c -control character */ char * breakout(ptr, quoted, paux) register char **ptr; char **paux; char *quoted; { register char *str = *ptr; char *base; short count = 0; char opc = 0; char clc = 0; char immode = 0; char isaux = 0; char buf[256]; short di = 0; *quoted = 0; *paux = NULL; while (*str == ' ') ++str; if (!*str) return(NULL); *ptr = str; base = str; while (*str) { if (immode) { if (di != sizeof(buf)-1) buf[di++] = *str; ++str; continue; } if (count == 0) { if (*str == ' ') break; if (*str == '\'' || *str == ')') clc = *str; if (*str == '`') { opc = '`'; clc = '\''; } if (*str == '(') { opc = '('; clc = ')'; } } if (*str == opc) { ++count; if (str == *ptr) { *quoted = 1; base = ++str; continue; } } if (*str == clc) { --count; if (count == 0 && *quoted) /* end of argument */ break; if (str == *ptr && count < 0) { immode = 1; *quoted = 1; base = ++str; continue; } } /* * $varname $(varname) $`varname'. I.E. three forms are allowed, * which allows one to insert the string almost anywhere. The * first form names are limited to alpha-numerics, '-', and '_'. */ if (*str == '$') { register char *ptr; char c, ce; short len; ce = 0; /* first form */ ++str; /* skip $ */ if (*str == '(') { /* second form */ ce = ')'; ++str; } else if (*str == '`') { /* third form */ ce = '\''; ++str; } ptr = str; /* start of varname */ if (ce) { /* until end char OR */ while (*ptr && *ptr != ce) ++ptr; } else { /* smart end-varname */ while ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || (*ptr >= '0' && *ptr <= '9') || *ptr == '-' || *ptr == '_' ) { ++ptr; } } len = ptr - str; /* length of variable */ c = *ptr; *ptr = 0; /* temp. terminate \0 */ if (strcmp(str, "scanf") == 0) { *ptr = c; isaux = 1; if (di + strlen(String) < sizeof(buf)-1) { strcpy(buf + di, String); di += strlen(buf + di); } str += len; /* next string pos */ if (ce) ++str; continue; } if (strcmp(str, "filename") == 0) { *ptr = c; isaux = 1; if (di + strlen(Ep->Name) < sizeof(buf)-1) { strcpy(buf + di, Ep->Name); di += strlen(buf + di); } str += len; if (ce) ++str; continue; } if (strcmp(str, "colno") == 0) { *ptr = c; isaux = 1; if (di < sizeof(buf)-8) { sprintf(buf + di, "%ld", Ep->Column + 1); di += strlen(buf + di); } str += len; if (ce) ++str; continue; } if (strcmp(str, "lineno") == 0) { *ptr = c; isaux = 1; if (di < sizeof(buf)-8) { sprintf(buf + di, "%ld", Ep->Line + 1); di += strlen(buf + di); } str += len; if (ce) ++str; continue; } if (ptr = getvar(str)) { str[len] = c; isaux = 1; if (di + strlen(ptr) < sizeof(buf)-1) { strcpy(buf + di, ptr); di += strlen(buf + di); } str += len; if (ce) ++str; free(ptr); continue; } *ptr = c; --str; if (ce) --str; } if (*str == '^' && (str[1] & 0x1F)) { ++str; *str &= 0x1F; isaux = 1; } if (*str == '\\' && str[1]) { ++str; isaux = 1; } buf[di++] = *str++; } buf[di++] = 0; if (isaux) { *paux = malloc(di); strcpy(*paux, buf); base = *paux; } if (*str) { /* space ended */ *str = '\0'; *ptr = str + 1; /* next arg */ } else { *ptr = str; /* last arg */ } return(base); } \Rogue\Monster\ else echo "will not over write ./src/command.c" fi if [ `wc -c ./src/command.c | awk '{printf $1}'` -ne 17738 ] then echo `wc -c ./src/command.c | awk '{print "Got " $1 ", Expected " 17738}'` fi if `test ! -s ./src/cmd3.c` then echo "writing ./src/cmd3.c" cat > ./src/cmd3.c << '\Rogue\Monster\' /* * CMD3.C * * (C)Copyright 1988 by Matthew Dillon, All Rights Reserved * * SETFONT * IGNORECASE * SET * SETENV * UNSET * UNSETENV * CD */ #include "defs.h" #include <local/xmisc.h> #include <stdio.h> #define nomemory() { memoryfail = 1; } extern FONT *GetFont(); /* * SETFONT font size */ void do_setfont() { register FONT *font = GetFont(av[1], atoi(av[2])); register ED *ep = Ep; if (font) { if (ep->Font) CloseFont(ep->Font); ep->Font = font; SetFont(ep->Win->RPort, font); SetRast(ep->Win->RPort, 0); RefreshWindowFrame(ep->Win); set_window_params(); text_redisplay(); } else { title("Unable to find font"); } } do_ignorecase() { register ED *ep = Ep; if (av[1][0]) { switch(av[1][1] & 0x1F) { case 'n'&0x1F: ep->IgnoreCase = 1; break; case 'f'&0x1F: ep->IgnoreCase = 0; break; case 'o'&0x1F: ep->IgnoreCase = 1 - ep->IgnoreCase; break; } if (ep->IgnoreCase) title("Case InSensitive"); else title("Case Sensitive"); } } /* * av[1] */ do_cd() { long oldlock; long lock; oldlock = CurrentDir(Ep->dirlock); if (lock = Lock(av[1], SHARED_LOCK)) { UnLock(CurrentDir(oldlock)); Ep->dirlock = lock; } else { CurrentDir(oldlock); Abortcommand = 1; title("Unable to CD"); } } /* * VARIABLE SUPPORT! */ #define VARS struct _VARS VARS { MNODE Node; char *Name; char *Str; }; static MLIST SList = { (MNODE *)&SList.mlh_Tail, NULL, (MNODE *)&SList.mlh_Head }; void do_set() { register VARS *v; do_unset(); if (v = malloc(sizeof(VARS))) { if (v->Name = malloc(strlen(av[1])+1)) { if (v->Str = malloc(strlen(av[2])+1)) { AddHead(&SList, v); strcpy(v->Name, av[1]); strcpy(v->Str , av[2]); return; } free(v->Name); } free(v); } nomemory(); } do_setenv() { SetDEnv(av[1], av[2]); } do_unset() { register VARS *v; for (v = (VARS *)SList.mlh_Head; v->Node.mln_Succ; v = (VARS *)v->Node.mln_Succ) { if (strcmp(v->Name, av[1]) == 0) { Remove(v); free(v); free(v->Name); free(v->Str); break; } } } do_unsetenv() { register char *ptr = (char *)av[1]; register char *tmp = malloc(4+strlen(ptr)+1); if (tmp) { strcpy(tmp, "ENV:"); strcat(tmp, ptr); mountrequest(0); DeleteFile(tmp); mountrequest(1); free(tmp); } } /* * Search (1) internal list, (2) enviroment, (3) macros. The variable * is allocated with malloc(). NULL if not found. ENV: need not exist. */ char * getvar(find) char *find; { register char *str = NULL; { register VARS *v; for (v = (VARS *)SList.mlh_Head; v->Node.mln_Succ; v = (VARS *)v->Node.mln_Succ) { if (strcmp(v->Name, find) == 0) { if (str = malloc(strlen(v->Str)+1)) { strcpy(str, v->Str); return(str); } } } } mountrequest(0); str = GetDEnv(find); mountrequest(1); if (str) return(str); if ((str = keyspectomacro(find)) || (str = menutomacro(find))) { register char *ptr = malloc(strlen(str)+1); if (ptr) { strcpy(ptr, str); return(ptr); } } return(NULL); } \Rogue\Monster\ else echo "will not over write ./src/cmd3.c" fi if [ `wc -c ./src/cmd3.c | awk '{printf $1}'` -ne 3166 ] then echo `wc -c ./src/cmd3.c | awk '{print "Got " $1 ", Expected " 3166}'` fi if `test ! -s ./src/keyboard.c` then echo "writing ./src/keyboard.c" cat > ./src/keyboard.c << '\Rogue\Monster\' /* * KEYBOARD.C * * (C)Copyright 1987 by Matthew Dillon * * Handle keyboard related stuff such as keyboard mappings. Every time * a key is pressed, KEYCTL() is called with the code. KEYCTL() remembers * which qualifier keys are currently held down, and when a non-qualifier * key is pressed finds the hash entry for the key. If no hash entry * exists (e.g. you type a normal 'a') the default keymap is used. */ #include "defs.h" #include <stdio.h> extern ubyte *cqtoa(); typedef struct IOStdReq CIO; #define QUAL_SHIFT 0x01 #define QUAL_CTRL 0x02 #define QUAL_AMIGA 0x04 #define QUAL_ALT 0x08 #define QUAL_LMB 0x10 #define QUAL_MMB 0x20 #define QUAL_RMB 0x40 #define HASHSIZE 64 /* power of 2 */ #define HASHMASK (HASHSIZE-1) typedef struct _HASH { struct _HASH *next; /* next hash */ ubyte code; /* keycode */ ubyte mask; /* qual. mask */ ubyte qual; /* qual. comp */ ubyte stat; /* string static? */ char *str; /* command string */ } HASH; HASH *Hash[HASHSIZE]; struct Device *ConsoleDevice; ubyte ctoa[128]; ubyte cstoa[128]; void keyctl(im, code, qual) IMESS *im; register USHORT qual; { ubyte buf[256]; ubyte c2; short blen = 0; code &= 0xFF; if (im) { im->Qualifier &= ~IEQUALIFIER_REPEAT; blen = DeadKeyConvert(im, buf+1, 254, NULL); if (blen < 0) return; } c2 = 0; if (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) c2 |= QUAL_SHIFT; if (qual & (IEQUALIFIER_CONTROL)) c2 |= QUAL_CTRL; if (qual & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)) c2 |= QUAL_AMIGA; if (qual & (IEQUALIFIER_LALT|IEQUALIFIER_RALT)) c2 |= QUAL_ALT; if ((qual & IEQUALIFIER_CAPSLOCK) && blen == 1 && buf[1] >= 'a' && buf[1] <= 'z') c2 |= QUAL_SHIFT; if (qual & IEQUALIFIER_LEFTBUTTON) c2 |= QUAL_LMB; if (qual & IEQUALIFIER_MIDBUTTON) c2 |= QUAL_MMB; if (qual & (IEQUALIFIER_RBUTTON)) c2 |= QUAL_RMB; { register HASH *hash; for (hash = Hash[code&HASHMASK]; hash; hash = hash->next) { if (hash->code == code && (c2 & hash->mask) == hash->qual) break; } /* * Use hash entry only if not in command line mode, or if the * entry does not correspond to an alpha key. */ if (hash) { if (c2 || !Comlinemode || blen > 1 || !ctoa[code]) { strcpy(buf, hash->str); do_command(buf); return; } } } /* * No hash entry */ if (blen == 1) { buf[0] = '\''; buf[2] = 0; } else { buf[0] = '\`'; buf[blen+1] = '\''; } if (blen) do_command(buf); } dealloc_hash() { register HASH *hash, *hnext = NULL; register short i; for (i = 0; i < HASHSIZE; ++i) { for (hash = Hash[i]; hash; hash = hnext) { hnext = hash->next; if (!hash->stat) FreeMem(hash->str, strlen(hash->str)+1); FreeMem(hash, sizeof(HASH)); } Hash[i] = NULL; } } resethash() { register short i; CIO cio; static struct { char *from, *to; } defmap[] = { "esc", "esc", "c-esc", "recall", "return", "return insline up firstnb down", "enter", "return", "up", "up", "down", "down", "right", "right", "left", "left", "bs", "bs", "del", "del", "tab", "tab", "a-up", "scrollup", "a-down", "scrolldown", "a-r", "nextr", "a-u", "while cl (tlate -32 right)", "a-l", "while cu (tlate +32 right)", "s-up", "top", "s-down", "bottom", "s-right", "last", "s-left", "first", "s-tab", "backtab", "s-del", "deline", "s- ", "( )", /* shift space to space */ "c-1", "goto block", "c-c", "", /* break.. map to a nop */ "c-l", "wleft", "c-r", "wright", "c-i", "insertmode on", "c-o", "insertmode off", "c-j", "join", "c-s", "split first down", "c-del", "remeol", "c-n", "next", "c-p", "prev", "c-/", "escimm (find )", "c-]", "ref", "c-[", "ctags", "c-g", "escimm (goto )", "c-up", "pageup", "c-down", "pagedown", "c-q", "quit", "c-f", "reformat", "c-w", "wordwrap toggle", "f1", "escimm (insfile )", "f2", "escimm (newfile )", "f3", "escimm (newwindow newfile )", "f6", "saveold iconify", "f7", "escimm (bsave )", "f8", "saveold escimm (newfile )", "f9", "saveold", "f10", "saveold quit", "c-b", "block", "c-u", "unblock", "a-d", "bdelete", "a-c", "bcopy", "a-m", "bmove", "a-s", "bsource", "a-S", "unblock block block bsource", "L-lmb", "tomouse", /* left button */ "L-mmo", "tomouse", /* mouse move w/left held down */ "R-rmb", "iconify", /* right button */ NULL, NULL }; dealloc_hash(); OpenDevice("console.device", -1, &cio, 0); ConsoleDevice = cio.io_Device; keyboard_init(); for (i = 0; defmap[i].from; ++i) { ubyte code, qual; if (get_codequal(defmap[i].from, &code, &qual)) addhash(code, 1, 0xFF, qual, defmap[i].to); } } returnoveride(n) { HASH *hash; static ubyte *str; static int stat; for (hash = Hash[0x44&HASHMASK]; hash; hash = hash->next) { if (hash->code == 0x44 && hash->qual == 0) { if (n) { str = (ubyte *)hash->str; stat= hash->stat; hash->str = "return"; hash->stat = 1; } else { if (str == NULL) { remhash(0x44, -1, 0); } else { hash->str = (char *)str; hash->stat= stat; } } return(0); } } if (n) { addhash(0x44, 1, 0xFF, 0, "return"); str = NULL; } } addhash(code, stat, mask, qual, str) ubyte code, stat, mask, qual; ubyte *str; { register HASH **p, *hash; hash = *(p = &Hash[code&HASHMASK]); while (hash) { if (hash->code == code && hash->qual == qual && hash->mask == mask) { if (!hash->stat) FreeMem(hash->str, strlen(hash->str)+1); goto newstr; } hash = *(p = &hash->next); } *p = hash = (HASH *)AllocMem(sizeof(HASH), 0); hash->next = NULL; newstr: hash->code = code; hash->stat = stat; hash->mask = mask; hash->qual = qual; hash->str = (char *)str; if (!stat) /* if not static */ hash->str = (char *)strcpy(AllocMem(strlen(str)+1, 0), str); } remhash(code, mask, qual) ubyte code, mask, qual; { register HASH *hash, **p; hash = *(p = &Hash[code&HASHMASK]); while (hash) { if (hash->code == code && hash->qual == qual && hash->mask == mask) { if (!hash->stat) FreeMem(hash->str, strlen(hash->str)+1); *p = hash->next; FreeMem(hash, sizeof(HASH)); return(1); } hash = *(p = &hash->next); } return(0); } char * keyspectomacro(str) char *str; { HASH *hash; ubyte code, qual; if (get_codequal(str, &code, &qual)) { for (hash = Hash[code&HASHMASK]; hash; hash = hash->next) { if (hash->code == code) { if (hash->qual == (qual & hash->mask)) { return(hash->str); } } } } return(NULL); } do_map() { ubyte code, qual; if (get_codequal(av[1], &code, &qual)) { addhash(code, 0, 0xFF, qual, av[2]); } else { title("Unknown Key"); } } do_unmap() /* key */ { ubyte code, qual; if (get_codequal(av[1], &code, &qual)) { remhash(code, -1, qual); } else { title("Unknown Command"); } } do_clearmap() { resethash(); } /* * SAVEMAP file * SAVESMAP file */ do_savemap() { char sysalso; char err = 0; char buf[256]; long xfi; register int i; register HASH *hash; register ubyte *ptr; xfi = xfopen(av[1], "w", 512); if (xfi) { sysalso = av[0][4] == 's'; for (i = 0; i < HASHSIZE; ++i) { for (hash = Hash[i]; hash; hash = hash->next) { if (hash->stat == 0 || sysalso) { char soc = '('; char eoc = ')'; char ksoc = '('; char keoc = ')'; short len; for (ptr = (ubyte *)hash->str; *ptr; ++ptr) { if (*ptr == '(') break; if (*ptr == '\`') { soc = '\`'; eoc = '\''; break; } } len = strlen(ptr = cqtoa(hash->code, hash->qual)) - 1; if (ptr[len] == '(' || ptr[len] == ')') { ksoc = '\`'; keoc = '\''; } sprintf(buf, "map %c%s%c %c%s%c\n", ksoc, cqtoa(hash->code, hash->qual), keoc, soc, hash->str, eoc); xfwrite(xfi, buf, strlen(buf)); } } } xfclose(xfi); if (err) title ("Unable to Write"); else title ("OK"); } else { title("Unable to open file"); } } /* * Nitty Gritty. * * keyboard_init: initialize for get_codequal() and cqtoa() * get_codequal: convert a qualifier-string combo to a keycode and qual. * cqtoa: convert a keycode and qual to a qual & string */ #define LN(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|d) long lname[] = { LN('e','s','c', 0 ), LN('f','1', 0 , 0 ), LN('f','2', 0 , 0 ), LN('f','3', 0 , 0 ), LN('f','4', 0 , 0 ), LN('f','5', 0 , 0 ), LN('f','6', 0 , 0 ), LN('f','7', 0 , 0 ), LN('f','8', 0 , 0 ), LN('f','9', 0 , 0 ), LN('f','1','0', 0 ), LN('d','e','l', 0 ), LN('b','a','c', 0 ), LN('b','s', 0 , 0 ), LN('t','a','b', 0 ), LN('h','e','l', 0 ), LN('r','e','t', 0 ), LN('u','p', 0 , 0 ), LN('d','o','w', 0 ), LN('r','i','g', 0 ), LN('l','e','f', 0 ), LN('e','n','t', 0 ), LN('n','k','-', 0 ), LN('n','k','.', 0 ), LN('n','k','0', 0 ), /* 24 */ LN('n','k','1', 0 ), LN('n','k','2', 0 ), LN('n','k','3', 0 ), LN('n','k','4', 0 ), LN('n','k','5', 0 ), LN('n','k','6', 0 ), LN('n','k','7', 0 ), LN('n','k','8', 0 ), LN('n','k','9', 0 ), LN('n','k','(', 0 ), LN('n','k',')', 0 ), LN('n','k','/', 0 ), /*34-36*/ LN('n','k','*', 0 ), LN('n','k','+', 0 ), LN('l','m','b',0xE8), LN('m','m','b',0xEA), LN('r','m','b',0xE9), LN('m','m','o',QMOVE), 0 }; /* * ESC: x1B * FUNCKEYS: x9B 30 7E to x9B 39 7E * DEL: x7E * BS: x08 * TAB: x09 * RETURN: x0D * HELP x9B 3F 7E * UP/D/L/R x9B 41/42/44/43 * NK0-9,-,.,ENTER * * Mouse buttons */ keyboard_init() { static struct InputEvent ievent = { NULL, IECLASS_RAWKEY }; ubyte buf[32]; register short i, q, len; lname[16] |= 0x44; lname[21] |= 0x43; for (i = 0; i < 128; ++i) { ievent.ie_Code = i; ievent.ie_Qualifier = 0; ievent.ie_position.ie_addr = NULL; len = RawKeyConvert(&ievent,buf,32,NULL); switch(len) { case 1: /* ESC/DEL/BS/TAB/NKx */ if (buf[0] >= 32 && buf[0] < 127) ctoa[i] = buf[0]; switch(buf[0]) { case 0x1B: lname[ 0] |= i; break; case 0x7F: lname[11] |= i; break; case 0x09: lname[14] |= i; break; case 0x08: lname[12] |= i; lname[13] |= i; break; case '(': if (i > 0x3A) lname[34] |= i; break; case ')': if (i > 0x3A) lname[35] |= i; break; case '/': if (i > 0x3A) lname[36] |= i; break; case '*': if (i > 0x3A) lname[37] |= i; break; case '-': if (i > 0x3A) lname[22] |= i; break; case '+': if (i > 0x3A) lname[38] |= i; break; case '.': if (i > 0x3A) lname[23] |= i; break; default: if (i >= 0x0F && buf[0] >= '0' && buf[0] <= '9') lname[24+buf[0]-'0'] |= i; } break; case 2: /* cursor */ if (buf[0] == 0x9B) { switch(buf[1]) { case 0x41: lname[17] |= i; break; case 0x42: lname[18] |= i; break; case 0x43: lname[19] |= i; break; case 0x44: lname[20] |= i; break; } } break; case 3: /* function/help */ if (buf[0] == 0x9B && buf[2] == 0x7E) { if (buf[1] == 0x3F) lname[15] |= i; if (buf[1] >= 0x30 && buf[1] <= 0x39) lname[buf[1]-0x30+1] |= i; } break; } } for (i = 0; i < 128; ++i) { ievent.ie_Code = i; ievent.ie_Qualifier = IEQUALIFIER_LSHIFT; ievent.ie_position.ie_addr = NULL; len = RawKeyConvert(&ievent,buf,32,NULL); if (len == 1) cstoa[i] = buf[0]; } { ubyte code, qual; get_codequal("c", &code, &qual); CtlC = code; } } ubyte * cqtoa(code, qual) register int qual; { static ubyte buf[32]; register ubyte *ptr = buf; register int i; if (qual & QUAL_SHIFT) *ptr++ = 's'; if (qual & QUAL_CTRL) *ptr++ = 'c'; if (qual & QUAL_ALT) *ptr++ = 'a'; if (qual & QUAL_AMIGA) *ptr++ = 'A'; if (qual & QUAL_LMB) *ptr++ = 'L'; if (qual & QUAL_MMB) *ptr++ = 'M'; if (qual & QUAL_RMB) *ptr++ = 'R'; if (qual) *ptr++ = '-'; for (i = 0; i < sizeof(lname)/sizeof(lname[0]); ++i) { if ((lname[i]&0xFF) == code) { *ptr++ = (lname[i]>>24); *ptr++ = (lname[i]>>16); *ptr++ = (lname[i]>>8); break; } } if (i == sizeof(lname)/sizeof(lname[0])) *ptr++ = ctoa[code]; *ptr++ = 0; return(buf); } get_codequal(str, pcode, pqual) ubyte *pcode, *pqual; register ubyte *str; { register ubyte qual; register short i; qual = 0; if (strlen(str) > 1) { for (; *str && *str != '-'; ++str) { if (*str == 's') qual |= QUAL_SHIFT; if (*str == 'c') qual |= QUAL_CTRL; if (*str == 'a') qual |= QUAL_ALT; if (*str == 'A') qual |= QUAL_AMIGA; if (*str == 'L') qual |= QUAL_LMB; if (*str == 'M') qual |= QUAL_MMB; if (*str == 'R') qual |= QUAL_RMB; if (!qual) goto notqual; } if (*str) ++str; } notqual: if (strlen(str) != 1) { /* long name */ register short shift = 24; register long mult = 0; *pqual = qual; while (*str && shift >= 8) { if (*str >= 'A' && *str <= 'Z') *str = *str - 'A' + 'a'; mult |= *str << shift; shift -= 8; ++str; } for (i = 0; lname[i]; ++i) { if (mult == (lname[i] & 0xFFFFFF00)) { *pcode = lname[i] & 0xFF; return(1); } } } else { /* single character keycap */ for (i = 0; i < sizeof(ctoa); ++i) { if (*str == ctoa[i]) { *pcode = i; *pqual = qual; return(1); } } for (i = 0; i < sizeof(cstoa); ++i) { if (*str == cstoa[i]) { *pcode = i; *pqual = qual|QUAL_SHIFT; return(1); } } } return(0); } \Rogue\Monster\ else echo "will not over write ./src/keyboard.c" fi if [ `wc -c ./src/keyboard.c | awk '{printf $1}'` -ne 14051 ] then echo `wc -c ./src/keyboard.c | awk '{print "Got " $1 ", Expected " 14051}'` fi echo "Finished archive 4 of 6" # if you want to concatenate archives, remove anything after this line exit -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.