mirror of
https://github.com/PDP-10/klh10.git
synced 2026-02-14 11:55:37 +00:00
For the ni20, add subcommands to the "dev ni0 ..." command.
This may be useful for debugging, given the subcommands as currently made available. The main loop command line parser is used to parse the subcommands. I don't think this is working for interactive subcommands yet.
This commit is contained in:
99
src/cmdline.h
Normal file
99
src/cmdline.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* CMDLINE.H - header file for command line processing functions
|
||||
*/
|
||||
/* Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
|
||||
/* Copyright © 2017 Olaf Seibert
|
||||
** All Rights Reserved
|
||||
**
|
||||
** This file is part of the KLH10 Distribution. Use, modification, and
|
||||
** re-distribution is permitted subject to the terms in the file
|
||||
** named "LICENSE", which contains the full text of the legal notices
|
||||
** and should always accompany this Distribution.
|
||||
**
|
||||
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
|
||||
**
|
||||
** This notice (including the copyright and warranty disclaimer)
|
||||
** must be included in all copies or derivations of this software.
|
||||
*/
|
||||
#ifndef CMDBUFLEN
|
||||
# define CMDBUFLEN 512
|
||||
#endif
|
||||
#ifndef CMDMAXARG
|
||||
# define CMDMAXARG 10
|
||||
#endif
|
||||
|
||||
struct cmd_s {
|
||||
struct cmkey_s *cmd_keys;/* Command table */
|
||||
int cmd_flags; /* State flags */
|
||||
char *cmd_prm; /* Pointer to command prompt */
|
||||
char *cmd_buf; /* Pointer to start of buffer */
|
||||
size_t cmd_blen; /* Size of buffer */
|
||||
int cmd_left; /* # chars left for current cmd being input */
|
||||
char *cmd_inp; /* Input deposit pointer */
|
||||
char *cmd_rdp; /* Readout pointer */
|
||||
size_t cmd_rleft; /* # chars left to read */
|
||||
|
||||
/* Provide all command routines with their desired arguments */
|
||||
char *cmd_arglin; /* Original pointer to start of args on line */
|
||||
int cmd_argc; /* # of tokens */
|
||||
char *cmd_argv[CMDMAXARG+1]; /* Array of token pointers */
|
||||
char *cmd_tdp; /* Next free loc in token buffer */
|
||||
size_t cmd_tleft; /* # chars free in token buffer */
|
||||
char cmd_tokbuf[CMDBUFLEN+CMDMAXARG];
|
||||
|
||||
#if 0
|
||||
char *cmd_wbf; /* Pointer to work buffer */
|
||||
size_t cmd_wblen; /* Size in chars */
|
||||
char *cmd_wbp; /* Current deposit ptr */
|
||||
size_t cmd_wbleft; /* # chars left */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define CMDF_ACTIVE 01 /* Activation char seen, execute accumulated cmd */
|
||||
#define CMDF_INACCUM 02 /* In accumulation phase */
|
||||
#define CMDF_NOPRM 040 /* Disable prompt */
|
||||
|
||||
struct cmkey_s {
|
||||
char *cmk_key;
|
||||
union cmnode *cmk_p;
|
||||
};
|
||||
struct cmrtn_s {
|
||||
void (*cmr_vect)(struct cmd_s *); /* Function to call */
|
||||
int cmr_flgs; /* Misc flags */
|
||||
char *cmr_synt; /* Arg syntax */
|
||||
char *cmr_help; /* Short one-line help */
|
||||
char *cmr_desc; /* Long description */
|
||||
};
|
||||
|
||||
#define CMRF_NOARG 01 /* Command takes no args */
|
||||
#define CMRF_TOKS 010 /* Command wants whole line tokenized, via cm */
|
||||
#define CMRF_TLIN 020 /* Command wants overall line arg, via cm */
|
||||
#define CMRF_CMPTR 040 /* Command wants just cmd state ptr */
|
||||
|
||||
union cmnode { /* All possible nodes for a keyword */
|
||||
struct cmrtn_s cmn_rtn;
|
||||
};
|
||||
|
||||
|
||||
/* Predeclarations */
|
||||
void cmdinit(struct cmd_s *, struct cmkey_s *, char *, char *, size_t);
|
||||
int cmdexec(struct cmd_s *);
|
||||
int cmdaccum(struct cmd_s *);
|
||||
|
||||
struct cmkey_s *cmdkeylookup(char *, struct cmkey_s *, struct cmkey_s **);
|
||||
char *cmdlsetup(struct cmd_s *);
|
||||
char *cmdlcopy(struct cmd_s *cm, char *line);
|
||||
void fc_gques(struct cmd_s *cm);
|
||||
void fc_ghelp(struct cmd_s *cm);
|
||||
|
||||
/* CMDDEF is used to define top-level commands. It does not accumulate
|
||||
** them into a table (C is far too puny for that) but gathers together
|
||||
** various information that a higher-level table can then point to.
|
||||
*/
|
||||
#define CMDDEF(deflab, func, flgs, argsyn, minihelp, longdesc) \
|
||||
static void func(struct cmd_s *); \
|
||||
static struct cmrtn_s deflab = { func, flgs, argsyn, minihelp, longdesc };
|
||||
|
||||
#define KEYSBEGIN(name) struct cmkey_s name[] = {
|
||||
#define KEYDEF(key,nod) { key, (union cmnode *)(&nod) },
|
||||
#define KEYSEND { 0, 0 } };
|
||||
|
||||
198
src/dvni20.c
198
src/dvni20.c
@@ -55,6 +55,7 @@ static int decosfcclossage;
|
||||
#include "kn10dev.h"
|
||||
#include "kn10ops.h"
|
||||
#include "dvni20.h"
|
||||
#include "cmdline.h"
|
||||
#include "prmstr.h" /* For parameter parsing */
|
||||
|
||||
#if KLH10_DEV_DPNI20 /* Event handling and dev sub-proc stuff! */
|
||||
@@ -238,6 +239,7 @@ static w10_t ni20_datai(struct device *d);
|
||||
static int ni20_init(struct device *d, FILE *of);
|
||||
static void ni20_reset(struct device *d);
|
||||
static void ni20_powoff(struct device *d);
|
||||
static int ni20_cmd(struct device *d, FILE *of, char *cmdline);
|
||||
#if KLH10_DEV_DPNI20
|
||||
static void ni20_evhsdon(struct device *d, struct dvevent_s *evp);
|
||||
static void ni20_evhrwak(struct device *d, struct dvevent_s *evp);
|
||||
@@ -327,22 +329,16 @@ static char *niprmtab[] = {
|
||||
static int pareth(char *cp, unsigned char *adr);
|
||||
static int parip(char *cp, unsigned char *adr);
|
||||
|
||||
/* NI20_CONF - Parse configuration string and set defaults.
|
||||
** At this point, device has just been created, but not yet bound
|
||||
** or initialized.
|
||||
** NOTE that some strings are dynamically allocated! Someday may want
|
||||
** to clean them up nicely if config fails or device is uncreated.
|
||||
/* Set defaults for all configurable parameters
|
||||
*/
|
||||
|
||||
static int
|
||||
ni20_conf(FILE *f, char *s, struct ni20 *ni)
|
||||
ni20_conf_clear(struct ni20 *ni)
|
||||
{
|
||||
int i, ret = TRUE;
|
||||
struct prmstate_s prm;
|
||||
char buff[200];
|
||||
long lval;
|
||||
|
||||
/* First set defaults for all configurable parameters */
|
||||
DVDEBUG(ni) = FALSE;
|
||||
ni->ni_ifnam = NULL;
|
||||
ni->ni_ifmeth = NULL;
|
||||
@@ -363,6 +359,22 @@ ni20_conf(FILE *f, char *s, struct ni20 *ni)
|
||||
ni->ni_dpidly = 5; /* Conservative 5-second timeout for T10/T20 */
|
||||
ni->ni_dpdbg = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* NI20_CONF - Parse configuration string and set defaults.
|
||||
** At this point, device has just been created, but not yet bound
|
||||
** or initialized.
|
||||
** NOTE that some strings are dynamically allocated! Someday may want
|
||||
** to clean them up nicely if config fails or device is uncreated.
|
||||
*/
|
||||
|
||||
static int
|
||||
ni20_conf(FILE *f, char *s, struct ni20 *ni)
|
||||
{
|
||||
int i, ret = TRUE;
|
||||
struct prmstate_s prm;
|
||||
char buff[200];
|
||||
long lval;
|
||||
|
||||
prm_init(&prm, buff, sizeof(buff),
|
||||
s, strlen(s),
|
||||
@@ -620,12 +632,14 @@ dvni20_create(FILE *f, char *s)
|
||||
ni->ni_dv.dv_coni = ni20_coni;
|
||||
ni->ni_dv.dv_datao = ni20_datao;
|
||||
ni->ni_dv.dv_datai = ni20_datai;
|
||||
ni->ni_dv.dv_cmd = ni20_cmd;
|
||||
|
||||
ni->ni_dv.dv_bind = NULL; /* Not a controller!! */
|
||||
ni->ni_dv.dv_init = ni20_init; /* Set up own post-bind init */
|
||||
ni->ni_dv.dv_reset = ni20_reset; /* System reset (clear stuff) */
|
||||
ni->ni_dv.dv_powoff = ni20_powoff; /* Power-off cleanup */
|
||||
|
||||
ni20_conf_clear(ni); /* Set all defaults */
|
||||
if (!ni20_conf(f, s, ni)) /* Do configuration stuff */
|
||||
return NULL;
|
||||
|
||||
@@ -769,7 +783,7 @@ ni20_reset(struct device *d)
|
||||
ni20_clear((struct ni20 *)d);
|
||||
}
|
||||
|
||||
/* NI20_QUIT - Tells the IMP process to quit
|
||||
/* NI20_QUIT - Tells the DPNI20 process to quit
|
||||
** and clean up resources such as networking tunnels.
|
||||
*/
|
||||
static void
|
||||
@@ -3442,6 +3456,172 @@ ni20_ioend(register struct device *drv,
|
||||
/* Now if no errors, check for secondary TCR and initiate it? */
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
** "dev ni0 xxx" subcommands
|
||||
*/
|
||||
|
||||
struct cmd_ni20_s {
|
||||
struct cmd_s ni20_cmd;
|
||||
struct ni20 *ni20_dev;
|
||||
FILE *ni20_of;
|
||||
};
|
||||
|
||||
CMDDEF(cd_ques, fc_ques, CMRF_NOARG, NULL,
|
||||
"How to get help for the DEV NIx subcommand", "")
|
||||
CMDDEF(cd_help, fc_help, CMRF_TOKS, NULL,
|
||||
"Basic help for the DEV NIx subcommands", "")
|
||||
CMDDEF(cd_init, fc_init, CMRF_NOARG, NULL,
|
||||
"Initialize the NI20 unit", "")
|
||||
CMDDEF(cd_start, fc_start, CMRF_NOARG, NULL,
|
||||
"Start the NI20 unit", "")
|
||||
CMDDEF(cd_stop, fc_stop, CMRF_NOARG, NULL,
|
||||
"Stop the NI20 unit", "")
|
||||
CMDDEF(cd_powoff,fc_powoff, CMRF_NOARG, NULL,
|
||||
"Power the NI20 unit off", "")
|
||||
CMDDEF(cd_set, fc_set, CMRF_TLIN, NULL,
|
||||
"Dynamically change config settings (not all will work!)", "")
|
||||
#if KLH10_DEV_DPNI20
|
||||
CMDDEF(cd_dpquit,fc_dpquit, CMRF_NOARG, NULL,
|
||||
"Tell the Device Proc to quit", "")
|
||||
CMDDEF(cd_dpstart,fc_dpstart,CMRF_NOARG, NULL,
|
||||
"Start the Device Process for the NI20 unit", "")
|
||||
#endif /* KLH10_DEV_DPNI20 */
|
||||
|
||||
KEYSBEGIN(ni20keys)
|
||||
KEYDEF("?", cd_ques)
|
||||
KEYDEF("help", cd_help)
|
||||
KEYDEF("init", cd_init)
|
||||
KEYDEF("start", cd_start)
|
||||
KEYDEF("stop", cd_stop)
|
||||
KEYDEF("powoff", cd_powoff)
|
||||
KEYDEF("set", cd_set)
|
||||
#if KLH10_DEV_DPNI20
|
||||
KEYDEF("dpstart", cd_dpstart)
|
||||
KEYDEF("dpquit", cd_dpquit)
|
||||
#endif /* KLH10_DEV_DPNI20 */
|
||||
KEYSEND
|
||||
|
||||
static int
|
||||
ni20_cmd(struct device *d, FILE *of, char *cmdline)
|
||||
{
|
||||
static struct cmd_ni20_s ni20_command;
|
||||
static char cmdbuf[CMDBUFLEN]; /* Original command string buffer */
|
||||
|
||||
ni20_command.ni20_dev = (struct ni20 *)d;
|
||||
ni20_command.ni20_of = of;
|
||||
|
||||
cmdinit(&ni20_command.ni20_cmd, ni20keys, "NI20> ",
|
||||
cmdbuf, sizeof(cmdbuf));
|
||||
cmdlcopy(&ni20_command.ni20_cmd, cmdline);
|
||||
cmdexec(&ni20_command.ni20_cmd);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fc_ques(struct cmd_s *cm)
|
||||
{
|
||||
fc_gques(cm);
|
||||
}
|
||||
|
||||
static void
|
||||
fc_help(struct cmd_s *cm)
|
||||
{
|
||||
fc_ghelp(cm);
|
||||
}
|
||||
|
||||
static void
|
||||
fc_init(struct cmd_s *cm0)
|
||||
{
|
||||
struct cmd_ni20_s *cm = (struct cmd_ni20_s *)cm0;
|
||||
|
||||
ni20_init(&cm->ni20_dev->ni_dv, cm->ni20_of);
|
||||
}
|
||||
|
||||
static void
|
||||
fc_start(struct cmd_s *cm0)
|
||||
{
|
||||
struct cmd_ni20_s *cm = (struct cmd_ni20_s *)cm0;
|
||||
|
||||
ni20_start(cm->ni20_dev);
|
||||
}
|
||||
|
||||
static void
|
||||
fc_stop(struct cmd_s *cm0)
|
||||
{
|
||||
struct cmd_ni20_s *cm = (struct cmd_ni20_s *)cm0;
|
||||
|
||||
ni20_stop(cm->ni20_dev);
|
||||
}
|
||||
|
||||
static void
|
||||
fc_powoff(struct cmd_s *cm0)
|
||||
{
|
||||
struct cmd_ni20_s *cm = (struct cmd_ni20_s *)cm0;
|
||||
|
||||
ni20_powoff(&cm->ni20_dev->ni_dv);
|
||||
}
|
||||
|
||||
static void
|
||||
fc_set(struct cmd_s *cm0)
|
||||
{
|
||||
struct cmd_ni20_s *cm = (struct cmd_ni20_s *)cm0;
|
||||
|
||||
ni20_conf(cm->ni20_of, cm0->cmd_arglin, cm->ni20_dev);
|
||||
}
|
||||
|
||||
#if KLH10_DEV_DPNI20
|
||||
|
||||
static void
|
||||
fc_dpstart(struct cmd_s *cm0)
|
||||
{
|
||||
struct cmd_ni20_s *cm = (struct cmd_ni20_s *)cm0;
|
||||
struct ni20 *ni = cm->ni20_dev;
|
||||
FILE *of = cm->ni20_of;
|
||||
|
||||
fprintf(of, "[starting DP \"%s\"...", ni->ni_dpname);
|
||||
|
||||
/* HORRIBLE UGLY HACK: for AXP OSF/1 and perhaps other systems,
|
||||
** the virtual-runtime timer of setitimer() remains in effect even
|
||||
** for the child process of a fork()! To avoid this, we must
|
||||
** temporarily turn the timer off, then resume it after the fork
|
||||
** is safely out of the way.
|
||||
**
|
||||
** Otherise, the timer would go off and the unexpected signal would
|
||||
** chop down the DP subproc without any warning!
|
||||
**
|
||||
** Later this should be done in DPSUP.C itself, when I can figure a
|
||||
** good way to tell whether the code is part of the KLH10 or a DP
|
||||
** subproc.
|
||||
*/
|
||||
clk_suspend(); /* Clear internal clock if one */
|
||||
int res = dp_start(&ni->ni_dp, ni->ni_dpname);
|
||||
clk_resume(); /* Resume internal clock if one */
|
||||
|
||||
if (!res) {
|
||||
fprintf(of, " Start of DP \"%s\" failed!]\r\n",
|
||||
ni->ni_dpname);
|
||||
} else {
|
||||
fprintf(of, " started!]\r\n");
|
||||
}
|
||||
|
||||
/* Set state to "running", assume disabled.
|
||||
*/
|
||||
ni->ni_state = NI20_ST_RUN; /* Running disabled */
|
||||
ni->ni_dpstate = TRUE; /* Not quite matching other uses,
|
||||
* but required for dpquit() */
|
||||
}
|
||||
|
||||
static void
|
||||
fc_dpquit(struct cmd_s *cm0)
|
||||
{
|
||||
struct cmd_ni20_s *cm = (struct cmd_ni20_s *)cm0;
|
||||
|
||||
ni20_quit(cm->ni20_dev);
|
||||
}
|
||||
|
||||
#endif /* KLH10_DEV_DPNI20 */
|
||||
|
||||
|
||||
/* Massbus Data Channel routines.
|
||||
**
|
||||
|
||||
132
src/klh10.c
132
src/klh10.c
@@ -56,6 +56,7 @@
|
||||
#include "wfio.h"
|
||||
#include "fecmd.h"
|
||||
#include "feload.h"
|
||||
#include "cmdline.h"
|
||||
#include "prmstr.h"
|
||||
#include "dvcty.h" /* For cty_ functions */
|
||||
|
||||
@@ -151,87 +152,15 @@ static int cminchar(void); /* Funct to read from file or TTY */
|
||||
|
||||
#define CMDQCHAR '\\' /* Quote char for token parsing */
|
||||
|
||||
#ifndef CMDBUFLEN
|
||||
# define CMDBUFLEN 512
|
||||
#endif
|
||||
#ifndef CMDMAXARG
|
||||
# define CMDMAXARG 10
|
||||
#endif
|
||||
|
||||
struct cmd_s {
|
||||
int cmd_flags; /* State flags */
|
||||
char *cmd_prm; /* Pointer to command prompt */
|
||||
char *cmd_buf; /* Pointer to start of buffer */
|
||||
size_t cmd_blen; /* Size of buffer */
|
||||
int cmd_left; /* # chars left for current cmd being input */
|
||||
char *cmd_inp; /* Input deposit pointer */
|
||||
char *cmd_rdp; /* Readout pointer */
|
||||
size_t cmd_rleft; /* # chars left to read */
|
||||
|
||||
/* Provide all command routines with their desired arguments */
|
||||
char *cmd_arglin; /* Original pointer to start of args on line */
|
||||
int cmd_argc; /* # of tokens */
|
||||
char *cmd_argv[CMDMAXARG+1]; /* Array of token pointers */
|
||||
char *cmd_tdp; /* Next free loc in token buffer */
|
||||
size_t cmd_tleft; /* # chars free in token buffer */
|
||||
char cmd_tokbuf[CMDBUFLEN+CMDMAXARG];
|
||||
|
||||
#if 0
|
||||
char *cmd_wbf; /* Pointer to work buffer */
|
||||
size_t cmd_wblen; /* Size in chars */
|
||||
char *cmd_wbp; /* Current deposit ptr */
|
||||
size_t cmd_wbleft; /* # chars left */
|
||||
#endif
|
||||
} command;
|
||||
|
||||
#define CMDF_ACTIVE 01 /* Activation char seen, execute accumulated cmd */
|
||||
#define CMDF_INACCUM 02 /* In accumulation phase */
|
||||
#define CMDF_NOPRM 040 /* Disable prompt */
|
||||
|
||||
static char cmdbuf[CMDBUFLEN]; /* Original command string buffer */
|
||||
#if 0
|
||||
static char cmdwbf[CMDBUFLEN]; /* Working buffer */
|
||||
#endif
|
||||
|
||||
struct cmkey_s {
|
||||
char *cmk_key;
|
||||
union cmnode *cmk_p;
|
||||
};
|
||||
struct cmrtn_s {
|
||||
void (*cmr_vect)(struct cmd_s *); /* Function to call */
|
||||
int cmr_flgs; /* Misc flags */
|
||||
char *cmr_synt; /* Arg syntax */
|
||||
char *cmr_help; /* Short one-line help */
|
||||
char *cmr_desc; /* Long description */
|
||||
};
|
||||
|
||||
#define CMRF_NOARG 01 /* Command takes no args */
|
||||
#define CMRF_TOKS 010 /* Command wants whole line tokenized, via cm */
|
||||
#define CMRF_TLIN 020 /* Command wants overall line arg, via cm */
|
||||
#define CMRF_CMPTR 040 /* Command wants just cmd state ptr */
|
||||
|
||||
union cmnode { /* All possible nodes for a keyword */
|
||||
struct cmrtn_s cmn_rtn;
|
||||
};
|
||||
|
||||
|
||||
/* Predeclarations */
|
||||
void cmdinit(struct cmd_s *, char *, char *, size_t);
|
||||
int cmdexec(struct cmd_s *);
|
||||
int cmdaccum(struct cmd_s *);
|
||||
|
||||
struct cmkey_s *cmdkeylookup(char *, struct cmkey_s *, struct cmkey_s **);
|
||||
char *cmdlsetup(struct cmd_s *);
|
||||
static void slinlim(char *);
|
||||
|
||||
|
||||
/* CMDDEF is used to define top-level commands. It does not accumulate
|
||||
** them into a table (C is far too puny for that) but gathers together
|
||||
** various information that a higher-level table can then point to.
|
||||
*/
|
||||
#define CMDDEF(deflab, func, flgs, argsyn, minihelp, longdesc) \
|
||||
static void func(struct cmd_s *); \
|
||||
static struct cmrtn_s deflab = { func, flgs, argsyn, minihelp, longdesc };
|
||||
static struct cmd_s command;
|
||||
|
||||
CMDDEF(cd_ques, fc_ques, CMRF_NOARG, NULL,
|
||||
"How to get help", "")
|
||||
@@ -323,10 +252,6 @@ CMDDEF(cd_lights, fc_lights, CMRF_TLIN, "<hexaddr>",
|
||||
#endif
|
||||
|
||||
|
||||
#define KEYSBEGIN(name) struct cmkey_s name[] = {
|
||||
#define KEYDEF(key,nod) { key, (union cmnode *)(&nod) },
|
||||
#define KEYSEND { 0, 0 } };
|
||||
|
||||
KEYSBEGIN(fectbkeys)
|
||||
KEYDEF("?", cd_ques)
|
||||
KEYDEF("help", cd_help)
|
||||
@@ -525,7 +450,7 @@ fe_cmdloop(void)
|
||||
|
||||
/* Determine new prompt if necessary */
|
||||
if (cmdpromptnew || (omode != cpu.fe.fe_mode)) {
|
||||
cmdinit(&command, fe_cmprompt(cpu.fe.fe_mode),
|
||||
cmdinit(&command, fectbkeys, fe_cmprompt(cpu.fe.fe_mode),
|
||||
cmdbuf, sizeof(cmdbuf));
|
||||
omode = cpu.fe.fe_mode;
|
||||
prompted = FALSE;
|
||||
@@ -836,10 +761,12 @@ static int cmdargs_all(struct cmd_s *cm);
|
||||
static int cmdargs_n(struct cmd_s *cm, int n);
|
||||
|
||||
void cmdinit(struct cmd_s *cm,
|
||||
struct cmkey_s *keys,
|
||||
char *prompt,
|
||||
char *ibuf,
|
||||
size_t ilen)
|
||||
{
|
||||
cm->cmd_keys = keys;
|
||||
cm->cmd_flags = 0;
|
||||
cm->cmd_prm = prompt;
|
||||
cm->cmd_buf = ibuf;
|
||||
@@ -959,7 +886,7 @@ cmdexec(struct cmd_s *cm)
|
||||
|
||||
/* Have token, see if it's a command */
|
||||
stolower(cp); /* Force lowercase for lookup */
|
||||
argc = s_keylookup(cp, fectbkeys, sizeof(struct cmkey_s),
|
||||
argc = s_keylookup(cp, cm->cmd_keys, sizeof(struct cmkey_s),
|
||||
(void *)&key, (void *)&key2);
|
||||
if (argc <= 0) {
|
||||
printf("Unknown command: \"%s\"\n", cp);
|
||||
@@ -1005,7 +932,10 @@ cmdexec(struct cmd_s *cm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Fetch a command line from the front end console, or from a command
|
||||
** file.
|
||||
*/
|
||||
char *
|
||||
cmdlsetup(struct cmd_s *cm)
|
||||
{
|
||||
@@ -1050,6 +980,30 @@ cmdlsetup(struct cmd_s *cm)
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* CMDLCOPY - Copy a command line into the previously indicated buffer.
|
||||
*/
|
||||
char *
|
||||
cmdlcopy(struct cmd_s *cm, char *line)
|
||||
{
|
||||
int len = strlen(line);
|
||||
if (len > cm->cmd_blen) {
|
||||
len = cm->cmd_blen - 1;
|
||||
}
|
||||
|
||||
if (cpu.fe.fe_debug)
|
||||
fprintf(stderr, "[cmdlcopy]");
|
||||
|
||||
strncpy(cm->cmd_buf, line, len);
|
||||
cm->cmd_buf[len] = '\0';
|
||||
|
||||
cm->cmd_rdp = cm->cmd_buf;
|
||||
cm->cmd_inp = cm->cmd_buf + len;
|
||||
cm->cmd_rleft = len;
|
||||
cm->cmd_left = cm->cmd_blen - len;
|
||||
|
||||
return cm->cmd_buf;
|
||||
}
|
||||
|
||||
|
||||
/* CMDFLS - Flush whitespace from current command pos
|
||||
*/
|
||||
@@ -1158,6 +1112,12 @@ fc_ques(struct cmd_s *cm)
|
||||
printf("Type \"help\" or \"help <command>\" for help.\n");
|
||||
}
|
||||
|
||||
void
|
||||
fc_gques(struct cmd_s *cm)
|
||||
{
|
||||
fc_ques(cm);
|
||||
}
|
||||
|
||||
static void
|
||||
helpline(register struct cmkey_s *kp)
|
||||
{
|
||||
@@ -1187,13 +1147,13 @@ fc_help(struct cmd_s *cm)
|
||||
cp = cm->cmd_argv[0];
|
||||
|
||||
if (!cp || !*cp) { /* If no specific arg, show everything */
|
||||
for (kp = fectbkeys; kp->cmk_key; ++kp) {
|
||||
for (kp = cm->cmd_keys; kp->cmk_key; ++kp) {
|
||||
helpline(kp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
(void) s_keylookup(cp, (voidp_t)fectbkeys, sizeof(struct cmkey_s),
|
||||
(void) s_keylookup(cp, (voidp_t)cm->cmd_keys, sizeof(struct cmkey_s),
|
||||
(voidp_t *)&kp, (voidp_t *)&key2);
|
||||
if (!kp) {
|
||||
printf("Unknown command: \"%s\"\n", cp);
|
||||
@@ -1207,12 +1167,18 @@ fc_help(struct cmd_s *cm)
|
||||
}
|
||||
|
||||
/* More than one match, show each one */
|
||||
for (kp = fectbkeys; kp->cmk_key; ++kp) {
|
||||
for (kp = cm->cmd_keys; kp->cmk_key; ++kp) {
|
||||
if (smatch(cp, kp->cmk_key) > 0)
|
||||
helpline(kp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fc_ghelp(struct cmd_s *cm)
|
||||
{
|
||||
fc_help(cm);
|
||||
}
|
||||
|
||||
/* SLINLIM - Limit string to 1 line by chopping it at first EOL seen.
|
||||
*/
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user