|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 11895 (0x2e77) Types: TextFile Names: »cmdl.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Life/cmdl.c«
#ifdef SCCS static char *sccsid = "@(#)cmdl.c 1.31 2/2/85"; static char *cpyrid = "@(#)Copyright (C) 1985 by D Bell"; #endif #include "life.h" #include <sys/ioctl.h> /* list of line command routines */ int c_create(), c_destroy(), c_edit(), c_dumpmacros(), c_quit(); int c_frequency(), c_listobjects(), c_zero(), c_lock(), c_unlock(); int c_read(), c_write(), c_ttyinput(), c_gridchar(), c_nogrid(); int c_insert(), c_copy(), c_copyselect(), c_move(), c_moveselect(); int c_help(), c_rules(), c_endinputlevel(), c_undo(), c_rename(); int c_set(), c_variables(), c_type(), c_update(), c_wait(); /* flags for line commands */ #define F_NONE 0x0 /* no special condition */ #define F_NOARG 0x1 /* must not have an argument */ #define F_ARG1 0x2 /* must have at least one argument */ #define F_NORUN 0x4 /* illegal if running generations */ #define F_UPDATE 0x8 /* update status if command completes */ #define F_REDRAW 0x10 /* redraw screen if command completes */ #define F_ABBR 0x20 /* abbreviation works even if ambiguous */ /* * Dispatch table for line commands. Those commands which are ambiguous * must be defined so as to be contiguous in the table. A spaces delimits * the command itself from the help string for the command. */ struct cmdtab { char *c_name; /* command name */ int (*c_func)(); /* function to call */ int c_flags; /* flags for command */ } cmdtab[] = { "copy (current object to) obj", c_copy, F_ARG1|F_NORUN|F_ABBR, "copyselection (to) obj", c_copyselect, F_ARG1|F_NORUN, "create (object named) obj", c_create, F_ARG1|F_NORUN|F_REDRAW, "destroy (object named) obj", c_destroy, F_ARG1|F_NORUN, "dumpmacros (to) file", c_dumpmacros, F_ARG1|F_NORUN, "edit (object named) obj", c_edit, F_NORUN|F_REDRAW|F_ABBR, "endinputlevel", c_endinputlevel, F_NOARG|F_UPDATE, "frequency (of typeout is) expr", c_frequency, F_UPDATE, "gridcharacter (is) char", c_gridchar, F_REDRAW, "help", c_help, F_NONE|F_ABBR, "insert (object from) obj", c_insert, F_ARG1|F_NORUN|F_REDRAW|F_ABBR, "list (all objects)", c_listobjects, F_NORUN|F_ABBR, "lock (current object)", c_lock, F_NOARG|F_NORUN|F_UPDATE, "move (current object to) obj", c_move, F_ARG1|F_NORUN|F_REDRAW|F_ABBR, "moveselection (to) obj",c_moveselect,F_ARG1|F_NORUN|F_REDRAW, "nogrid", c_nogrid, F_NOARG|F_REDRAW, "quit (program)", c_quit, F_NOARG|F_ABBR, "read (commands from) file", c_read, F_ARG1|F_NORUN|F_REDRAW|F_ABBR, "rename (current object to) obj", c_rename, F_ARG1|F_UPDATE, "rules (for life are) born live", c_rules, F_NORUN|F_UPDATE, "set (variable) name (to) expr", c_set, F_ARG1|F_ABBR, "ttyinput", c_ttyinput, F_REDRAW, "type (value of expression) expr", c_type, F_ARG1|F_UPDATE|F_ABBR, "undo (last change)", c_undo, F_NOARG|F_NORUN|F_REDRAW|F_ABBR, "unlock (current object)", c_unlock, F_NOARG|F_NORUN|F_UPDATE, "updateview (to be current)", c_update, F_NOARG, "variables (are listed)", c_variables, F_NOARG|F_REDRAW|F_ABBR, "wait (for computations)", c_wait, F_NOARG, "write (current object to) file", c_write, F_ARG1|F_NORUN|F_ABBR, "zero (current object)", c_zero, F_NOARG|F_NORUN|F_REDRAW|F_ABBR, 0 /* ends the table */ }; /* * Read and execute a command line style command. This kind of command echoes, * and is terminated by an end of line. Numeric arguments are available. */ dolinecommand(arg1, arg2, got1, got2) { register char *name; /* command name */ register char *args; /* arguments for command */ register struct cmdtab *cmd; /* command structure */ register int flag; /* flags for command */ name = readstring("command: "); if ((*name == '\0') || (*name == '\n')) return; for (args = name; *args && (*args != ' ') && (*args != '\t'); args++) ; while ((*args == ' ') || (*args == '\t')) *args++ = '\0'; for (cmd = cmdtab; ; cmd++) { if (cmd->c_name == NULL) error("Unknown line command"); if (abbrev(name, cmd[0].c_name) == 0) continue; if (cmd->c_flags & F_ABBR) break; if (abbrev(name, cmd[1].c_name) == 0) break; if (strcmp(name, cmd[0].c_name) == 0) break; if (cmd[1].c_flags & F_ABBR) continue; error("Ambiguous line command"); } flag = cmd->c_flags; if (flag & F_NORUN) checkrun(); if ((flag & F_ARG1) && (*args == '\0')) error("Missing argument"); if ((flag & F_NOARG) && *args) error("Argument not allowed"); cmd->c_func(args, arg1, arg2, got1, got2); if (flag & F_UPDATE) update = 1; if (flag & F_REDRAW) redraw = 1; } /* Copy the current object into another object */ c_copy(cp) char *cp; /* destination object name */ { copyobject(curobj, getobject(cp)); } /* Copy the current selection into another object */ c_copyselect(cp) char *cp; /* destination object name */ { copymarkedobject(curobj, getobject(cp), MARK_USR); } /* Edit an object, creating it if necessary */ c_create(cp) char *cp; /* object to create */ { setobject(getobject(cp)); } /* Destroy an existing object */ c_destroy(cp) char *cp; /* object name */ { register struct object *obj; /* object to destroy */ obj = findobject(cp); if (obj == NULL) error("No such object"); destroyobject(obj); } /* Dump list of macros to file */ c_dumpmacros(cp) char *cp; /* file name */ { writemacros(cp); } /* Edit an existing object. A null argument implies the previous object. */ c_edit(cp) char *cp; /* object name */ { register struct object *obj; /* object to edit */ obj = prevobj; if (*cp) obj = findobject(cp); if (obj == NULL) error("No such object"); setobject(obj); } /* Undo the last change made to the current object */ c_undo() { moveobject(curobj, tempobject); moveobject(backupobject, curobj); moveobject(tempobject, backupobject); } /* End current input level */ c_endinputlevel() { if (curinput <= inputs) error("Cannot end top level input"); curinput->i_term(curinput); } /* Update the view even if inside of a loop or macro */ c_update() { update = 1; updateview(); } /* Wait until all outstanding generation computations are finished */ c_wait() { while ((stop == 0) && (genleft > 0)) { dogeneration(curobj); updateview(); } } /* Set output frequency */ c_frequency(cp) register char *cp; /* frequency string */ { register int freq; /* new frequency */ freq = 1; if (*cp) freq = getexpression(cp); if (freq <= 0) error("Illegal value"); frequency = freq; freqcount = freq; } /* Select the character used for the background of the screen */ c_gridchar(cp) register char *cp; /* grid character string */ { if (*cp == '\0') cp = "."; if ((*cp < ' ') || (cp[1] != '\0')) error("Bad grid character"); gridchar = *cp; } /* Set so we don`t see a grid on the screen */ c_nogrid() { gridchar = ' '; } /* Type list of line commands */ c_help() { register struct cmdtab *cmd; /* command structure */ register int count; dpywindow(0, -1, 0, -1); dpystr("\ The following table lists all line mode commands. Unique abbreviations are\n\ allowed. Commands shown with '*' can be abbreviated even when ambiguous.\n"); count = 0; for (cmd = cmdtab; cmd->c_name; cmd++) { if ((count++ % 2) == 0) dpychar('\n'); dpyprintf("%c %-35s", ((cmd->c_flags & F_ABBR) ? '*' : ' '), cmd->c_name); } dpychar('\n'); spacewait(); } /* Insert another object into this one */ c_insert(cp) char *cp; /* object name */ { register struct object *obj; /* object to insert */ obj = findobject(cp); if (obj == NULL) error("No such object"); cmark = MARK_USR; backup(); addobject(obj, curobj, RELATIVE); cmark = MARK_ANY; } /* Show list of objects */ c_listobjects(cp) register char *cp; /* option string */ { int all; /* true if want to see all objects */ all = ((*cp == '-') || (*cp == 'a')); listobjects(all); } /* Lock object so it can't be run */ c_lock() { curobj->o_lock = 1; genleft = 0; freqcount = frequency; } /* Unlock object so it can be run */ c_unlock() { curobj->o_lock = 0; } /* Rename the current object to something else */ c_rename(cp) register char *cp; /* new name */ { if (curobj->o_reserved) error("Cannot rename reserved object"); if (strlen(cp) > MAXNAME) error("Name too long"); if (findobject(cp)) error("Name already exists"); if (BADNAME(cp)) error("Cannot create reserved name"); strcpy(curobj->o_name, cp); } /* Move current object into another object */ c_move(cp) char *cp; /* destination object name */ { moveobject(curobj, getobject(cp)); } /* Move current selection into another object */ c_moveselect(cp) char *cp; /* destination object name */ { movemarkedobject(curobj, getobject(cp), MARK_USR); } /* Set the value of a variable */ c_set(cp) register char *cp; /* variable name */ { register char *exp; /* expression */ for (exp = cp; *exp && (*exp != ' ') && (*exp != '='); exp++) ; if (*exp == ' ') { /* skip spaces */ *exp++ = '\0'; while (*exp == ' ') exp++; } if (*exp == '\0') { /* no expression, set to zero */ setvariable(cp, 0); return; } if (*exp == '=') *exp++ = '\0'; setvariable(cp, getexpression(exp)); } /* Type the value of an expression */ c_type(cp) char *cp; /* expression */ { static char buf[20]; /* storage for string */ sprintf(buf, "%d\n", getexpression(cp));/* store value */ errorstring = buf; /* make it seen */ } /* Display the values of all the variables */ c_variables() { listvariables(); } /* Quit program */ c_quit() { dpyclose(); exit(0); } /* Read commands or object from file, defaulting extension if needed */ c_read(cp) register char *cp; /* file name */ { backup(); if (setfile(cp)) error("Cannot open input file"); } /* Set new life rules */ c_rules(cp) register char *cp; /* life rules string */ { register char *bp; /* born string */ register char *lp; /* live string */ if (*cp == '\0') cp = "3,23"; bp = cp; while ((*cp >= '0') && (*cp <= '8')) cp++; if (*cp == '\0') error("Missing rule string"); if ((*cp != ',') && (*cp != ' ') && (*cp != '\t')) { error("Bad born string"); } *cp++ = '\0'; while ((*cp == ',') || (*cp == ' ') || (*cp == '\t')) cp++; lp = cp; while ((*cp >= '0') && (*cp <= '8')) cp++; if (*cp != '\0') error("Bad live string"); for (cp = rules; cp < &rules[18]; cp++) *cp = 0; while (*bp) rules[*bp++ - '0'] = 1; while (*lp) rules[*lp++ - '0' + LIFE] = 1; bp = rulestring; for (cp = rules; cp < &rules[LIFE]; cp++) { if (*cp) *bp++ = '0' + (cp - rules); } *bp++ = ','; for (cp = &rules[LIFE]; cp < &rules[18]; cp++) { if (*cp) *bp++ = ('0' - LIFE) + (cp - rules); } *bp = '\0'; } /* * Read commands from the terminal. Useful in loops or command files. * If the -c argument is given, we don't do it if no input is ready. */ c_ttyinput(cp) register char *cp; /* pointer to argument string */ { int count; /* character count */ if ((*cp == '-') || (*cp == 'c')) { /* check for input */ count = 0; ioctl(STDIN, FIONREAD, &count); if (count == 0) return; } if (settty()) error("Nesting too deep"); } /* Write object to file */ c_write(cp, arg1, arg2, got1, got2) register char *cp; /* pointer to argument string */ { if (got1 == 0) arg1 = WRITECOLS; writeobject(curobj, cp, arg1?WRITEROWS:0, arg1); } /* Zero out current object */ c_zero() { register struct object *obj; /* current object */ obj = curobj; if (obj->o_lock) error("Object is locked"); backup(); zeroobject(obj); obj->o_gen = 0; obj->o_born = 0; obj->o_died = 0; obj->o_currow = 0; obj->o_curcol = 0; obj->o_prow = 0; obj->o_pcol = 0; obj->o_autoscale = 0; setscale(obj, 1); mode = M_MOVE; frequency = 1; freqcount = 1; } /* * See if one string is an abbreviation of another. This knows that * the second string contains spaces which terminate the comparison. * Returns nonzero if first string is an abbreviation. */ abbrev(str1, str2) register char *str1, *str2; /* strings */ { if ((str1 == NULL) || (str2 == NULL)) return(0); while (*str1) if (*str1++ != *str2++) return(0); return(1); }