From c7484ceaaa152ffbd2e2f685adc9f3871a2b9dff Mon Sep 17 00:00:00 2001 From: krcroft Date: Sun, 19 Jan 2020 21:53:42 -0800 Subject: [PATCH] Improve compliance when printing drive labels --- include/drives.h | 1 + include/support.h | 2 ++ src/dos/dos_programs.cpp | 13 +++++-------- src/dos/drives.cpp | 13 +++++++++++++ src/misc/support.cpp | 10 ++++++++++ 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/include/drives.h b/include/drives.h index ba5b19bd..daa08c35 100644 --- a/include/drives.h +++ b/include/drives.h @@ -30,6 +30,7 @@ bool WildFileCmp(const char * file, const char * wild); void Set_Label(char const * const input, char * const output, bool cdrom); +std::string To_Label(const char* name); class DriveManager { public: diff --git a/include/support.h b/include/support.h index 2ddf3245..7087027e 100644 --- a/include/support.h +++ b/include/support.h @@ -93,5 +93,7 @@ Bits ConvHexWord(char * word); void trim(std::string& str); void upcase(std::string &str); void lowcase(std::string &str); +void strip_punctuation(std::string &str); + #endif diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index dec34170..e68d5603 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -144,16 +144,13 @@ public: if (ret) { dta.GetResult(name,size,date,time,attr); DOS_FindNext(); //Mark entry as invalid - } else name[0] = 0; - - /* Change 8.3 to 11.0 */ - char* dot = strchr(name,'.'); - if(dot && (dot - name == 8) ) { - name[8] = name[9];name[9] = name[10];name[10] = name[11];name[11] = 0; + } else { + name[0] = 0; } - + std::string label = To_Label(name); root[1] = 0; //This way, the format string can be reused. - WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),root, Drives[d]->GetInfo(),name); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"), + root, Drives[d]->GetInfo(), label.c_str()); } dos.dta(save_dta); } diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 7a93a17f..a601bc5f 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -73,6 +73,19 @@ checkext: return true; } + +std::string To_Label(const char* name) { + // Reformat the name per the DOS label specification: + // - Upper-case, up to 11 ASCII characters + // - Internal spaces allowed but no: tabs ? / \ | . , ; : + = [ ] < > " ' + std::string label(name); + trim(label); // strip front-and-back white-space + strip_punctuation(label); // strip all punctuation + label.resize(11); // collapse remainder to (at-most) 11 chars + upcase(label); + return label; +} + void Set_Label(char const * const input, char * const output, bool cdrom) { Bitu togo = 8; Bitu vnamePos = 0; diff --git a/src/misc/support.cpp b/src/misc/support.cpp index 0a01c6b9..823067af 100644 --- a/src/misc/support.cpp +++ b/src/misc/support.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,15 @@ void trim(std::string &str) { if (loc != std::string::npos) str.erase(loc+1); } +void strip_punctuation(std::string &str) { + str.erase( + std::remove_if( + str.begin(), + str.end(), + [](unsigned char c){ return std::ispunct(c); }), + str.end()); +} + /* Ripped some source from freedos for this one.