Skip to content

Commit

Permalink
Merge pull request #4523 from maxpat78/patch_intl
Browse files Browse the repository at this point in the history
International support in LABEL, COPY, DEL builtin commands
  • Loading branch information
joncampbell123 authored Oct 11, 2023
2 parents cae8080 + 444b0fc commit e845834
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 46 deletions.
22 changes: 14 additions & 8 deletions src/dos/dos_programs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6917,7 +6917,7 @@ class LABEL : public Program
{
public:
void Help() {
WriteOut("Creates, changes, or deletes the volume label of a drive.\n\nLABEL [drive:][label]\n\n [drive:]\tSpecifies the drive letter\n [label]\tSpecifies the volume label\n");
WriteOut(MSG_Get("PROGRAM_LABEL_HELP"));
}
void Run() override
{
Expand Down Expand Up @@ -6966,11 +6966,11 @@ class LABEL : public Program

/* if the label is longer than 11 chars or contains a dot, MS-DOS will reject it and then prompt for another label */
if (label.length() > 11) {
WriteOut("Label is too long (more than 11 characters).\n");
WriteOut(MSG_Get("PROGRAM_LABEL_TOOLONG"));
label.clear();
}
else if (label.find_first_of(".:/\\") != std::string::npos) {
WriteOut("Label has invalid characters.\n");
WriteOut(MSG_Get("PROGRAM_LABEL_BADCHARS"));
label.clear();
}

Expand All @@ -6979,9 +6979,9 @@ class LABEL : public Program
std::string clabel = Drives[drive]->GetLabel();

if (!clabel.empty())
WriteOut("Volume in drive %c is %s\n",drive+'A',clabel.c_str());
WriteOut(MSG_Get("PROGRAM_LABEL_VOLUMEIS"),drive+'A',clabel.c_str());
else
WriteOut("Volume in drive %c has no label\n",drive+'A');
WriteOut(MSG_Get("PROGRAM_LABEL_NOLABEL"),drive+'A');
}

/* If no label is provided, MS-DOS will prompt the user whether to delete the label. */
Expand All @@ -6994,16 +6994,16 @@ class LABEL : public Program

inshell = true;
do {
WriteOut("Delete the volume label (Y/N)? ");
WriteOut(MSG_Get("PROGRAM_LABEL_DELETE"));
s = 1;
DOS_ReadFile(STDIN,&c,&s);
WriteOut("\n");
if (s != 1 || c == 3) {inshell=false;return;}
ans = uint8_t(tolower(char(c)));
} while (!(ans == 'y' || ans == 'n'));
} while (!(ans == MSG_Get("INT21_6523_YESNO_CHARS")[0] || ans == MSG_Get("INT21_6523_YESNO_CHARS")[1]));
inshell = false;

if (ans != 'y') return;
if (ans != MSG_Get("INT21_6523_YESNO_CHARS")[0]) return;
}

/* delete then create the label */
Expand Down Expand Up @@ -9500,6 +9500,12 @@ void DOS_SetupPrograms(void) {
MSG_Add("PROGRAM_KEYB_LAYOUTNOTFOUND","No layout in %s for codepage %i\n");
MSG_Add("PROGRAM_KEYB_INVCPFILE","None or invalid codepage file for layout %s\n\n");
MSG_Add("INT21_6523_YESNO_CHARS", "yn");
MSG_Add("PROGRAM_LABEL_HELP", "Creates, changes, or deletes the volume label of a drive.\n\nLABEL [drive:][label]\n\n [drive:]\tSpecifies the drive letter\n [label]\tSpecifies the volume label\n");
MSG_Add("PROGRAM_LABEL_DELETE", "Delete the volume label (Y/N)? ");
MSG_Add("PROGRAM_LABEL_TOOLONG", "Label is too long (more than 11 characters).\n");
MSG_Add("PROGRAM_LABEL_BADCHARS", "Label has invalid characters.\n");
MSG_Add("PROGRAM_LABEL_VOLUMEIS", "Volume in drive %c is %s\n");
MSG_Add("PROGRAM_LABEL_NOLABEL", "Volume in drive %c has no label\n");
MSG_Add("PROGRAM_MODE_USAGE","Configures system devices.\n\n"
"\033[34;1mMODE\033[0m display-type :display-type codes are "
"\033[1mCO80\033[0m, \033[1mBW80\033[0m, \033[1mCO40\033[0m, \033[1mBW40\033[0m, or \033[1mMONO\033[0m\n"
Expand Down
5 changes: 5 additions & 0 deletions src/shell/shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1415,10 +1415,13 @@ void SHELL_Init() {
MSG_Add("SHELL_CMD_MKDIR_EXIST","Directory already exists - %s\n");
MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to create directory - %s\n");
MSG_Add("SHELL_CMD_RMDIR_ERROR","Invalid path, not directory, or directory not empty - %s\n");
MSG_Add("SHELL_CMD_RMDIR_FULLTREE_CONFIRM", "Delete directory \"%s\" and all its subdirectories? (Y/N)?");
MSG_Add("SHELL_CMD_RMDIR_SINGLE_CONFIRM", "Delete file \"%s\" (Y/N)?");
MSG_Add("SHELL_CMD_RENAME_ERROR","Unable to rename - %s\n");
MSG_Add("SHELL_CMD_ATTRIB_GET_ERROR","Unable to get attributes: %s\n");
MSG_Add("SHELL_CMD_ATTRIB_SET_ERROR","Unable to set attributes: %s\n");
MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete - %s\n");
MSG_Add("SHELL_CMD_DEL_CONFIRM", "Delete %s (Y/N)?");
MSG_Add("SHELL_CMD_DEL_SURE","All files in directory will be deleted!\nAre you sure [Y/N]?");
MSG_Add("SHELL_SYNTAXERROR","Syntax error\n");
MSG_Add("SHELL_CMD_SET_NOT_SET","Environment variable %s not defined.\n");
Expand Down Expand Up @@ -1450,6 +1453,7 @@ void SHELL_Init() {
MSG_Add("SHELL_CMD_COPY_CONFIRM","Overwrite %s (Yes/No/All)?");
MSG_Add("SHELL_CMD_COPY_NOSPACE","Insufficient disk space - %s\n");
MSG_Add("SHELL_CMD_COPY_ERROR","Copy error - %s\n");
MSG_Add("SHELL_CMD_COPY_NOSELF", "File cannot be copied onto itself\r\n");
MSG_Add("SHELL_CMD_SUBST_DRIVE_LIST","The currently mounted local drives are:\n");
MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Unable to remove, drive not in use.\n");
MSG_Add("SHELL_CMD_SUBST_IN_USE","Target drive is already in use.\n");
Expand All @@ -1458,6 +1462,7 @@ void SHELL_Init() {
MSG_Add("SHELL_CMD_SUBST_FAILURE","SUBST: There is an error in your command line.\n");
MSG_Add("SHELL_CMD_VTEXT_ON","DOS/V V-text is currently enabled.\n");
MSG_Add("SHELL_CMD_VTEXT_OFF","DOS/V V-text is currently disabled.\n");
MSG_Add("SHELL_ALLFILES_CHAR", "a");

std::string mapper_keybind = mapper_event_keybind_string("host");
if (mapper_keybind.empty()) mapper_keybind = "unbound";
Expand Down
91 changes: 53 additions & 38 deletions src/shell/shell_cmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,15 @@ void DOS_Shell::CMD_CLS(char * args) {

void DOS_Shell::CMD_DELETE(char * args) {
HELP("DELETE");
bool optP=ScanCMDBool(args,"P");
bool optP=ScanCMDBool(args,"P");
bool optF=ScanCMDBool(args,"F");
bool optQ=ScanCMDBool(args,"Q");

const char ch_y = MSG_Get("INT21_6523_YESNO_CHARS")[0];
const char ch_n = MSG_Get("INT21_6523_YESNO_CHARS")[1];
const char ch_Y = toupper(ch_y);
const char ch_N = toupper(ch_n);

// ignore /f, /s, /ar, /as, /ah and /aa switches for compatibility
ScanCMDBool(args,"S");
ScanCMDBool(args,"AR");
Expand Down Expand Up @@ -549,28 +554,28 @@ void DOS_Shell::CMD_DELETE(char * args) {
first_2:
uint8_t c;uint16_t n=1;
DOS_ReadFile (STDIN,&c,&n);
do switch (c) {
case 'n': case 'N':
{
DOS_WriteFile (STDOUT,&c, &n);
DOS_ReadFile (STDIN,&c,&n);
do switch (c) {
case 0xD: WriteOut("\n");dos.dta(save_dta);return;
case 0x03: dos.dta(save_dta);return;
case 0x08: WriteOut("\b \b"); goto first_2;
} while (DOS_ReadFile (STDIN,&c,&n));
}
case 'y': case 'Y':
{
DOS_WriteFile (STDOUT,&c, &n);
DOS_ReadFile (STDIN,&c,&n);
do switch (c) {
case 0xD: WriteOut("\n"); goto continue_1;
case 0x03: dos.dta(save_dta);return;
case 0x08: WriteOut("\b \b"); goto first_2;
} while (DOS_ReadFile (STDIN,&c,&n));
}
case 0xD: WriteOut("\n"); goto first_1;
do switch (c) {
if(c == ch_n || c == ch_N)
{
DOS_WriteFile(STDOUT, &c, &n);
DOS_ReadFile(STDIN, &c, &n);
do switch(c) {
case 0xD: WriteOut("\n"); dos.dta(save_dta); return;
case 0x03: dos.dta(save_dta); return;
case 0x08: WriteOut("\b \b"); goto first_2;
} while(DOS_ReadFile(STDIN, &c, &n));
}
if(c == ch_y || c == ch_Y)
{
DOS_WriteFile(STDOUT, &c, &n);
DOS_ReadFile(STDIN, &c, &n);
do switch(c) {
case 0xD: WriteOut("\n"); goto continue_1;
case 0x03: dos.dta(save_dta); return;
case 0x08: WriteOut("\b \b"); goto first_2;
} while(DOS_ReadFile(STDIN, &c, &n));
}
case 0xD: WriteOut("\n"); goto first_1;
case 0x03: dos.dta(save_dta);return;
case '\t':
case 0x08:
Expand Down Expand Up @@ -644,14 +649,14 @@ void DOS_Shell::CMD_DELETE(char * args) {
strcpy(end,name);
strcpy(lend,lname);
if (optP) {
WriteOut("Delete %s (Y/N)?", uselfn?sfull:full);
WriteOut(MSG_Get("SHELL_CMD_DEL_CONFIRM"), uselfn?sfull:full);
uint8_t c;
uint16_t n=1;
DOS_ReadFile (STDIN,&c,&n);
if (c==3) break;
c = c=='y'||c=='Y' ? 'Y':'N';
c = c==ch_y||c== ch_Y ? ch_Y:ch_N;
WriteOut("%c\r\n", c);
if (c=='N') {lfn_filefind_handle=uselfn?LFN_FILEFIND_INTERNAL:LFN_FILEFIND_NONE;res = DOS_FindNext();continue;}
if (c==ch_N) {lfn_filefind_handle=uselfn?LFN_FILEFIND_INTERNAL:LFN_FILEFIND_NONE;res = DOS_FindNext();continue;}
}
if (strlen(full)) {
std::string pfull=(uselfn||strchr(full, ' ')?(full[0]!='"'?"\"":""):"")+std::string(full)+(uselfn||strchr(full, ' ')?(full[strlen(full)-1]!='"'?"\"":""):"");
Expand Down Expand Up @@ -717,6 +722,10 @@ extern bool ctrlbrk;
std::vector<std::string> tdirs;

static bool doDeltree(DOS_Shell * shell, char * args, DOS_DTA dta, bool optY, bool first) {
const char ch_y = MSG_Get("INT21_6523_YESNO_CHARS")[0];
const char ch_n = MSG_Get("INT21_6523_YESNO_CHARS")[1];
const char ch_Y = toupper(ch_y);
const char ch_N = toupper(ch_n);
char spath[DOS_PATHLENGTH],sargs[DOS_PATHLENGTH+4],path[DOS_PATHLENGTH+4],full[DOS_PATHLENGTH],sfull[DOS_PATHLENGTH+2];
if (!DOS_Canonicalize(args,full)||strrchr_dbcs(full,'\\')==NULL) { shell->WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return false; }
if (!DOS_GetSFNPath(args,spath,false)) {
Expand Down Expand Up @@ -764,12 +773,12 @@ static bool doDeltree(DOS_Shell * shell, char * args, DOS_DTA dta, bool optY, bo
if(attr&DOS_ATTR_DIRECTORY) {
if (strcmp(name, ".")&&strcmp(name, "..")) {
if (!optY&&first) {
shell->WriteOut("Delete directory \"%s\" and all its subdirectories? (Y/N)?", uselfn?sfull:full);
shell->WriteOut(MSG_Get("SHELL_CMD_RMDIR_FULLTREE_CONFIRM"), uselfn ? sfull : full);
DOS_ReadFile (STDIN,&c,&n);
if (c==3) {shell->WriteOut("^C\r\n");break;}
c = c=='y'||c=='Y' ? 'Y':'N';
c = c==ch_y||c==ch_Y ? ch_Y:ch_N;
shell->WriteOut("%c\r\n", c);
if (c=='N') {res = DOS_FindNext();continue;}
if (c==ch_N) {res = DOS_FindNext();continue;}
}
fdir=true;
strcat(spath, name);
Expand All @@ -778,12 +787,12 @@ static bool doDeltree(DOS_Shell * shell, char * args, DOS_DTA dta, bool optY, bo
}
} else {
if (!optY&&first) {
shell->WriteOut("Delete file \"%s\" (Y/N)?", uselfn?sfull:full);
shell->WriteOut(MSG_Get("SHELL_CMD_RMDIR_SINGLE_CONFIRM"), uselfn ? sfull : full);
DOS_ReadFile (STDIN,&c,&n);
if (c==3) {shell->WriteOut("^C\r\n");break;}
c = c=='y'||c=='Y' ? 'Y':'N';
c = c==ch_y||c==ch_Y ? ch_Y:ch_N;
shell->WriteOut("%c\r\n", c);
if (c=='N') {res = DOS_FindNext();continue;}
if (c==ch_N) {res = DOS_FindNext();continue;}
}
pfull=(uselfn||strchr(uselfn?sfull:full, ' ')?((uselfn?sfull:full)[0]!='"'?"\"":""):"")+std::string(uselfn?sfull:full)+(uselfn||strchr(uselfn?sfull:full, ' ')?((uselfn?sfull:full)[strlen(uselfn?sfull:full)-1]!='"'?"\"":""):"");
cfiles.push_back(pfull);
Expand Down Expand Up @@ -2273,10 +2282,15 @@ struct copysource {
copysource():filename(""),concat(false){ };
};


void DOS_Shell::CMD_COPY(char * args) {
HELP("COPY");
static std::string defaulttarget = ".";
const char ch_y = MSG_Get("INT21_6523_YESNO_CHARS")[0];
const char ch_n = MSG_Get("INT21_6523_YESNO_CHARS")[1];
const char ch_Y = toupper(ch_y);
const char ch_N = toupper(ch_n);
const char ch_a = MSG_Get("SHELL_ALLFILES_CHAR")[0];
const char ch_A = toupper(ch_a);
StripSpaces(args);
/* Command uses dta so set it to our internal dta */
RealPt save_dta=dos.dta();
Expand Down Expand Up @@ -2555,7 +2569,7 @@ void DOS_Shell::CMD_COPY(char * args) {
strcpy(nametmp, nameSource);
if (!oldsource.concat && (!strcasecmp(nameSource, nameTarget) || !strcasecmp(nametmp, nameTarget)))
{
WriteOut("File cannot be copied onto itself\r\n");
WriteOut(MSG_Get("SHELL_CMD_COPY_NOSELF"));
dos.dta(save_dta);
DOS_CloseFile(sourceHandle);
if (targetHandle)
Expand All @@ -2574,11 +2588,11 @@ void DOS_Shell::CMD_COPY(char * args) {
{
DOS_ReadFile (STDIN,&c,&n);
if (c==3) {dos.dta(save_dta);DOS_CloseFile(sourceHandle);dos.echo=echo;return;}
if (c=='y'||c=='Y') {WriteOut("Y\r\n", c);break;}
if (c=='n'||c=='N') {WriteOut("N\r\n", c);break;}
if (c=='a'||c=='A') {WriteOut("A\r\n", c);optY=true;break;}
if (c==ch_y||c==ch_Y) {WriteOut("%c\r\n", ch_Y);break;}
if (c==ch_n||c==ch_N) {WriteOut("%c\r\n", ch_N);break;}
if (c==ch_a||c==ch_A) {WriteOut("%c\r\n", ch_A);optY=true;break;}
}
if (c=='n'||c=='N') {DOS_CloseFile(sourceHandle);ret = DOS_FindNext();continue;}
if (c==ch_n||c==ch_N) {DOS_CloseFile(sourceHandle);ret = DOS_FindNext();continue;}
}
if (!exist&&size) {
int drive=strlen(nameTarget)>1&&(nameTarget[1]==':'||nameTarget[2]==':')?(toupper(nameTarget[nameTarget[0]=='"'?1:0])-'A'):-1;
Expand Down Expand Up @@ -2674,6 +2688,7 @@ void DOS_Shell::CMD_COPY(char * args) {
Drives[DOS_GetDefaultDrive()]->EmptyCache();
}


/* NTS: WARNING, this function modifies the buffer pointed to by char *args */
void DOS_Shell::CMD_SET(char * args) {
HELP("SET");
Expand Down

0 comments on commit e845834

Please sign in to comment.