home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * 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();
-
- 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[] = {
- "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,
- "chfilename", 1, 0, do_chfilename,
- "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,
- "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,
- "ref", 0, 0, do_refs,
- "reformat", 0, 0, do_reformat,
- "remeol", 0, CF_COK, do_remeol,
- "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,
- "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,
- "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;
-
- 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");
- }
- }
-
-
- do_quit()
- {
- extern char Quitflag;
-
- Quitflag = 1;
- }
-
- do_execute()
- {
- Execute(av[1], NULL, NULL);
- }
-
- /*
- * 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) {
- buf[di++] = *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;
- }
- }
- if (*str == '$') {
- if (strncmp(str, "$scanf", 6) == 0) {
- isaux = 1;
- strcpy(buf + di, String);
- di = strlen(buf);
- str += 6;
- continue;
- }
- if (strncmp(str, "$filename", 9) == 0) {
- isaux = 1;
- strcpy(buf + di, Ep->Name);
- di = strlen(buf);
- str += 9;
- continue;
- }
- }
- 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);
- }
-
-
-