From 53666d5f27719468408d6463789757ddd6a5b759 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 8 Sep 2019 12:25:41 +0000 Subject: [PATCH] Extra DIR sorting options patch by Saga Musix Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4255 --- src/shell/shell_cmds.cpp | 100 +++++++++++++++++++++++++++++++++++---- 1 file changed, 91 insertions(+), 9 deletions(-) diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index e1d688c3..88cb072c 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -25,6 +25,7 @@ #include "../dos/drives.h" #include "support.h" #include "control.h" +#include #include #include #include @@ -407,7 +408,31 @@ static void FormatNumber(Bit32u num,char * buf) { return; }; sprintf(buf,"%d",numb); -} +} + +struct DtaResult { + char name[DOS_NAMELENGTH_ASCII]; + Bit32u size; + Bit16u date; + Bit16u time; + Bit8u attr; + + static bool compareName(const DtaResult &lhs, const DtaResult &rhs) { return strcmp(lhs.name, rhs.name) < 0; } + static bool compareExt(const DtaResult &lhs, const DtaResult &rhs) { return strcmp(lhs.getExtension(), rhs.getExtension()) < 0; } + static bool compareSize(const DtaResult &lhs, const DtaResult &rhs) { return lhs.size < rhs.size; } + static bool compareDate(const DtaResult &lhs, const DtaResult &rhs) { return lhs.date < rhs.date || (lhs.date == rhs.date && lhs.time < rhs.time); } + + const char * getExtension() const { + const char * ext = empty_string; + if (name[0] != '.') { + ext = strrchr(name, '.'); + if (!ext) ext = empty_string; + } + return ext; + } + +}; + void DOS_Shell::CMD_DIR(char * args) { HELP("DIR"); @@ -421,7 +446,7 @@ void DOS_Shell::CMD_DIR(char * args) { line = std::string(args) + " " + value; args=const_cast(line.c_str()); } - + bool optW=ScanCMDBool(args,"W"); ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); @@ -430,6 +455,29 @@ void DOS_Shell::CMD_DIR(char * args) { } bool optB=ScanCMDBool(args,"B"); bool optAD=ScanCMDBool(args,"AD"); + bool optAminusD=ScanCMDBool(args,"A-D"); + // Sorting flags + bool reverseSort = false; + bool optON=ScanCMDBool(args,"ON"); + if (ScanCMDBool(args,"O-N")) { + optON = true; + reverseSort = true; + } + bool optOD=ScanCMDBool(args,"OD"); + if (ScanCMDBool(args,"O-D")) { + optOD = true; + reverseSort = true; + } + bool optOE=ScanCMDBool(args,"OE"); + if (ScanCMDBool(args,"O-E")) { + optOE = true; + reverseSort = true; + } + bool optOS=ScanCMDBool(args,"OS"); + if (ScanCMDBool(args,"O-S")) { + optOS = true; + reverseSort = true; + } char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); @@ -488,13 +536,45 @@ void DOS_Shell::CMD_DIR(char * args) { return; } - do { /* File name and extension */ - char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; - dta.GetResult(name,size,date,time,attr); + std::vector results; + + do { /* File name and extension */ + DtaResult result; + dta.GetResult(result.name,result.size,result.date,result.time,result.attr); + + /* Skip non-directories if option AD is present, or skip dirs in case of A-D */ + if(optAD && !(result.attr&DOS_ATTR_DIRECTORY) ) continue; + else if(optAminusD && (result.attr&DOS_ATTR_DIRECTORY) ) continue; + + results.push_back(result); + + } while ( (ret=DOS_FindNext()) ); + + if (optON) { + // Sort by name + std::sort(results.begin(), results.end(), DtaResult::compareName); + } else if (optOE) { + // Sort by extension + std::sort(results.begin(), results.end(), DtaResult::compareExt); + } else if (optOD) { + // Sort by date + std::sort(results.begin(), results.end(), DtaResult::compareDate); + } else if (optOS) { + // Sort by size + std::sort(results.begin(), results.end(), DtaResult::compareSize); + } + if (reverseSort) { + std::reverse(results.begin(), results.end()); + } + + for (std::vector::iterator iter = results.begin(); iter != results.end(); iter++) { + + char * name = iter->name; + Bit32u size = iter->size; + Bit16u date = iter->date; + Bit16u time = iter->time; + Bit8u attr = iter->attr; - /* Skip non-directories if option AD is present */ - if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue; - /* output the file */ if (optB) { // this overrides pretty much everything @@ -542,7 +622,9 @@ void DOS_Shell::CMD_DIR(char * args) { if (optP && !(++p_count%(22*w_size))) { CMD_PAUSE(empty_string); } - } while ( (ret=DOS_FindNext()) ); + } + + if (optW) { if (w_count%5) WriteOut("\n"); }