Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 363 → Rev 364

/svarcom/command.c
80,31 → 80,6
}
 
 
static int explode_progparams(char *s, char const **argvlist) {
int si = 0, argc = 0;
for (;;) {
/* skip to next non-space character */
while (s[si] == ' ') si++;
/* end of string? */
if (s[si] == '\r') break;
/* set argv ptr */
argvlist[argc++] = s + si;
/* find next space */
while (s[si] != ' ' && s[si] != '\r') si++;
/* is this end of string? */
if (s[si] == '\r') {
s[si] = 0;
break;
}
/* not end: terminate arg and look for next one */
s[si++] = 0;
}
/* terminate argvlist with a NULL value */
argvlist[argc] = NULL;
return(argc);
}
 
 
static void buildprompt(char *s, const char *fmt) {
for (; *fmt != 0; fmt++) {
if (*fmt != '$') {
206,6 → 181,30
}
 
 
static void run_as_external(const char far *cmdline) {
char buff[256];
char const *argvlist[256];
int i, n;
/* copy buffer to a near var (incl. trailing CR), insert a space before
every slash to make sure arguments are well separated */
n = 0;
i = 0;
for (;;) {
if (cmdline[i] == '/') buff[n++] = ' ';
buff[n++] = cmdline[i++];
if (buff[n] == 0) break;
}
 
cmd_explode(buff, cmdline, argvlist);
 
/* for (i = 0; argvlist[i] != NULL; i++) printf("arg #%d = '%s'\r\n", i, argvlist[i]); */
 
/* must be an external command then. this call should never return, unless
* the other program failed to be executed. */
execvp(argvlist[0], argvlist);
}
 
 
int main(int argc, char **argv) {
struct config cfg;
unsigned short rmod_seg;
239,26 → 238,35
}
 
for (;;) {
int i, n, argcount;
char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
char buff[256];
char const *argvlist[256];
 
/* revert input history terminator to \r */
if (cmdline[-1] != 0) {
cmdline[(unsigned short)(cmdline[-1])] = '\r';
}
 
{
/* print shell prompt */
char buff[256];
char *promptptr = buff;
buildprompt(promptptr, "$p$g"); /* TODO: prompt should be configurable via environment */
_asm {
push ax
push dx
mov ah, 0x09
mov dx, promptptr
int 0x21
pop dx
pop ax
}
}
 
/* wait for user input */
_asm {
push ax
push bx
push cx
push dx
push ds
 
/* is DOSKEY support present? (INT 2Fh, AX=4800h, returns non-zero in AL if present) */
286,6 → 294,10
 
DONE:
pop ds
pop dx
pop cx
pop bx
pop ax
}
printf("\r\n");
 
292,34 → 304,21
/* if nothing entered, loop again */
if (cmdline[-1] == 0) continue;
 
/* copy buffer to a near var (incl. trailing CR), insert a space before
every slash to make sure arguments are well separated */
n = 0;
for (i = 0; i < cmdline[-1] + 1; i++) {
if (cmdline[i] == '/') buff[n++] = ' ';
buff[n++] = cmdline[i];
}
buff[n] = 0;
/* replace \r by a zero terminator */
cmdline[(unsigned char)(cmdline[-1])] = 0;
 
argcount = explode_progparams(buff, argvlist);
/* move pointer forward to skip over any leading spaces */
while (*cmdline == ' ') cmdline++;
 
/* if no args found (eg. all-spaces), loop again */
if (argcount == 0) continue;
 
/* for (i = 0; i < argcount; i++) printf("arg #%d = '%s'\r\n", i, argvlist[i]); */
 
/* is it about quitting? */
if (imatch(argvlist[0], "exit")) break;
 
/* try running it as an internal command */
/* try matching (and executing) an internal command */
{
int ecode = cmd_process(argcount, argvlist, *rmod_envseg, cmdline);
int ecode = cmd_process(*rmod_envseg, cmdline);
if (ecode >= 0) *lastexitcode = ecode;
if (ecode >= -1) continue; /* command is internal but did not set an exit code */
if (ecode >= -1) continue; /* internal command executed */
}
 
/* must be an external command then */
execvp(argvlist[0], argvlist);
/* if here, then this was not an internal command */
run_as_external(cmdline);
 
/* execvp() replaces the current process by the new one
if I am still alive then external command failed to execute */