1
0
Fork 0

Added patches from Guillaume Serre and Justin. Changed copy to strip *.* from target

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1008
This commit is contained in:
Peter Veenstra 2003-05-12 09:19:55 +00:00
parent f64cceafdf
commit 27d7b02a31
4 changed files with 164 additions and 68 deletions

View file

@ -50,14 +50,13 @@ void SHELL_AddAutoexec(char * line,...) {
sprintf((autoexec_data+auto_len),"%s\r\n",buf);
}
DOS_Shell::DOS_Shell():Program(){
input_handle=STDIN;
echo=true;
exit=false;
bf=0;
memset(&old.buffer,0,CMD_OLDSIZE);
old.size=0;
completion_start = NULL;
}
@ -65,11 +64,14 @@ DOS_Shell::DOS_Shell():Program(){
Bit32u DOS_Shell::GetRedirection(char *s, char **ifn, char **ofn) {
char *output = strrchr(s, '>');
if (output) {
*output = 0;
// while (!isalnum(*output)) output++;
}
return 1;
}
}
void DOS_Shell::ParseLine(char * line) {
@ -81,7 +83,7 @@ void DOS_Shell::ParseLine(char * line) {
line=trim(line);
Bit32u num=0; /* Number of commands in this line */
num = GetRedirection(line,&in, &out);
num = GetRedirection(line, &in, &out);
/* TODO in and out redirection */

View file

@ -24,31 +24,30 @@
static SHELL_Cmd cmd_list[]={
{ "CD", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"},
{ "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"},
{ "CD", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"},
{ "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP"},
{ "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP"},
{ "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"},
{ "DEL", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
{ "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
{ "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
{ "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"},
{ "ECHO.", 1, &DOS_Shell::CMD_EHCODOT, "SHELL_CMD_ECHO_HELP"},
{ "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"},
{ "HELP", 0, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"},
{ "MD", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"},
{ "RD", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"},
{ "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"},
{ "MD", 1, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"},
{ "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"},
{ "RD", 1, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"},
{ "SET", 0, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"},
{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"},
{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"},
{ "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"},
{ "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"},
{ "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"},
{ "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"},
{ "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"},
{ "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"},
/*
"CHDIR", 0, &DOS_Shell::CMD_CHDIR, "Change Directory",
"MKDIR", 0, &DOS_Shell::CMD_MKDIR, "Make Directory",
"RMDIR", 0, &DOS_Shell::CMD_RMDIR, "Remove Directory",
*/
{ 0,0,0,0}
};
@ -235,7 +234,7 @@ void DOS_Shell::CMD_DIR(char * args) {
/* Make a full path in the args */
if (!DOS_Canonicalize(args,path)) {
WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH"));
WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));
return;
}
*(strrchr(path,'\\')+1)=0;
@ -332,7 +331,7 @@ void DOS_Shell::CMD_COPY(char * args) {
char pathTarget[DOS_PATHLENGTH];
if (!DOS_Canonicalize(source,pathSource)) {
WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH"));
WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));
return;
}
// cut search pattern
@ -340,10 +339,13 @@ void DOS_Shell::CMD_COPY(char * args) {
if (pos) *(pos+1) = 0;
if (!DOS_Canonicalize(target,pathTarget)) {
WriteOut(MSG_Get("SHELL_CMD_ILLEGAL_PATH"));
WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));
return;
}
// add '\\' if target is a directoy
char* temp = strstr(pathTarget,"*.*");
if(temp) *temp = 0;//strip off *.* from target
// add '\\' if target is a directoy
if (pathTarget[strlen(pathTarget)-1]!='\\') {
if (DOS_FindFirst(pathTarget,0xffff)) {
dta.GetResult(name,size,date,time,attr);
@ -520,8 +522,8 @@ void DOS_Shell::CMD_REM(char * args) {
}
void DOS_Shell::CMD_PAUSE(char * args){
WriteOut(MSG_Get("SHELL_CMD_PAUSE"));
Bit8u c;Bit16u n=1;
WriteOut(MSG_Get("SHELL_CMD_PAUSE"));
Bit8u c;Bit16u n=1;
DOS_ReadFile (STDIN,&c,&n);
}

View file

@ -26,6 +26,9 @@
#include "callback.h"
#include "setup.h"
#include <string>
#include <list>
#define CMD_MAXLINE 4096
#define CMD_MAXCMDS 20
#define CMD_OLDSIZE 4096
@ -46,11 +49,19 @@ public:
CommandLine * cmd;
};
class DOS_Shell : public Program {
private:
std::list<std::string> l_history, l_completion;
char *completion_start;
Bit16u completion_index;
public:
DOS_Shell();
void Run(void);
void RunInternal(void); //for command /C
/* A load of subfunctions */
@ -87,12 +98,6 @@ public:
BatchFile * bf;
bool echo;
bool exit;
struct {
char buffer[CMD_OLDSIZE];
Bitu index;
Bitu size;
} old;
};
struct SHELL_Cmd {

View file

@ -40,11 +40,14 @@ static void outs(char * str) {
}
void DOS_Shell::InputCommand(char * line) {
char * prev=old.buffer;
char * reader;
Bitu size=CMD_MAXLINE-1;
Bit8u c;Bit16u n=1;
Bitu str_len=0;Bitu str_index=0;
Bit16u len;
line[0] = '\0';
std::list<std::string>::iterator it_history = l_history.begin(), it_completion = l_completion.begin();
while (size) {
dos.echo=false;
@ -58,41 +61,75 @@ void DOS_Shell::InputCommand(char * line) {
{
DOS_ReadFile(input_handle,&c,&n);
switch (c) {
case 0x3d: /* F3 */
if (strlen(old.buffer)>str_len) {
reader=&old.buffer[str_len];
while ((c=*reader++)) {
line[str_index]=c;
str_len++;
str_index++;
size--;
if (!l_history.size()) break;
it_history = l_history.begin();
if (it_history != l_history.end() && it_history->length() > str_len) {
const char *reader = &(it_history->c_str())[str_len];
while ((c = *reader++)) {
line[str_index ++] = c;
DOS_WriteFile(STDOUT,&c,&n);
}
str_len = str_index = it_history->length();
size = CMD_MAXLINE - str_index - 1;
}
break;
default:
case 0x4B: /* LEFT */
if (str_index) {
outc(8);
str_index --;
}
break;
case 0x4D: /* RIGHT */
if (str_index < str_len) {
outc(line[str_index++]);
}
break;
case 0x48: /* UP */
if (it_history == l_history.end()) break;
for (;str_index>0; str_index--) {
// removes all characters
outc(8); outc(' '); outc(8);
}
strcpy(line, it_history->c_str());
len = it_history->length();
str_len = str_index = len;
size = CMD_MAXLINE - str_index - 1;
DOS_WriteFile(STDOUT, (Bit8u *)line, &len);
it_history ++;
if (it_history == l_history.end()) it_history = l_history.begin();
break;
default:
break;
}
};
break;
case 0x08: /* BackSpace */
if (str_index>0) {
Bit32u str_remain=str_len-str_index;
if (str_index) {
outc(8);
Bit32u str_remain=str_len - str_index;
if (str_remain) {
memcpy(&line[str_index-1],&line[str_index],str_remain);
line[str_len]=0;
memmove(&line[str_index-1],&line[str_index],str_remain);
line[--str_len]=0;
str_index --;
/* Go back to redraw */
for (;str_remain>0;str_remain--) {
outc(8);
}
for (Bit16u i=str_index; i < str_len; i++)
outc(line[i]);
} else {
line[--str_index] = '\0';
str_len--;
}
str_index--;str_len--;
outc(8);
outc(' ');
outc(8);
outc(' '); outc(8);
// moves the cursor left
while (str_remain--) outc(8);
}
break;
case 0x0a: /* New Line not handled */
@ -103,35 +140,85 @@ void DOS_Shell::InputCommand(char * line) {
size=0; //Kill the while loop
break;
case'\t':
{
Bit8u c=' ';Bit16u n=1;
for(Bitu i=0; i !=4 ;i++)
{
line[str_index]=c;
str_len++;//This should depend on insert being active
str_index++;
size--;
DOS_WriteFile(STDOUT,&c,&n);
{
if (l_completion.size()) {
it_completion ++;
if (it_completion == l_completion.end()) it_completion = l_completion.begin();
} else {
// build new completion list
// get completion mask
char *completion_start = strrchr(line, ' ');
if (completion_start) {
completion_start ++;
completion_index = str_index - strlen(completion_start);
} else {
completion_start = line;
completion_index = 0;
}
// build the completion list
char mask[DOS_PATHLENGTH];
if (completion_start) {
strcpy(mask, completion_start);
// not perfect when line already contains wildcards, but works
strcat(mask, "*.*");
} else {
strcpy(mask, "*.*");
}
bool res = DOS_FindFirst(mask, 0xffff & ~DOS_ATTR_VOLUME);
if (!res) break; // TODO: beep
DOS_DTA dta(dos.dta);
char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
while (res) {
dta.GetResult(name,size,date,time,attr);
// add result to completion list
if (strcmp(name, ".") && strcmp(name, ".."))
l_completion.push_back(name);
res=DOS_FindNext();
}
it_completion = l_completion.begin();
}
if (it_completion->length()) {
for (;str_index > completion_index; str_index--) {
// removes all characters
outc(8); outc(' '); outc(8);
}
strcpy(&line[completion_index], it_completion->c_str());
len = it_completion->length();
str_len = str_index = completion_index + len;
size = CMD_MAXLINE - str_index - 1;
DOS_WriteFile(STDOUT, (Bit8u *)it_completion->c_str(), &len);
}
}
break;
default:
if (l_completion.size()) l_completion.clear();
line[str_index]=c;
str_index ++;
if (str_index > str_len) line[str_index] = '\0';
str_len++;//This should depend on insert being active
str_index++;
size--;
DOS_WriteFile(STDOUT,&c,&n);
break;
}
}
/* String is inputted now save it in the buffer */
line[str_len]=0;
if (!str_len) return;
str_len++;
//Not quite perfect last entries can get screwed :)
size_t first_len=strlen(old.buffer)+1;
memmove(&old.buffer[first_len],&old.buffer[0],CMD_OLDSIZE-first_len);
strcpy(old.buffer,line);
// add command line to history
l_history.push_front(line); it_history = l_history.begin();
if (l_completion.size()) l_completion.clear();
}
void DOS_Shell::Execute(char * name,char * args) {