From 714902e17c91200f53d0ad9a356466ee60b59d98 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Thu, 24 Dec 2009 20:51:21 +0100 Subject: Changed some stuff about the Shell Some applets are now externalized : cat free halt ls reboot uptime Also added some colors --- Source/Applications/Shell/Applets/cat.cpp | 34 ++++++++++ Source/Applications/Shell/Applets/free.cpp | 12 ++++ Source/Applications/Shell/Applets/halt.cpp | 13 ++++ Source/Applications/Shell/Applets/ls.cpp | 95 ++++++++++++++++++++++++++++ Source/Applications/Shell/Applets/reboot.cpp | 13 ++++ Source/Applications/Shell/Applets/rot13.cpp | 30 --------- Source/Applications/Shell/Applets/uptime.cpp | 26 ++++++++ Source/Applications/Shell/Makefile | 2 +- Source/Applications/Shell/Shell-fs.class.cpp | 64 +------------------ Source/Applications/Shell/Shell.class.cpp | 77 ++++++++++++++++------ Source/Applications/Shell/Shell.class.h | 19 +++++- Source/Kernel/VTManager/SimpleVT.class.h | 6 ++ Source/Library/Common/BasicString.class.cpp | 9 +++ Source/Library/Common/BasicString.class.h | 3 + Source/Library/Common/Map.class.h | 15 ++--- 15 files changed, 296 insertions(+), 122 deletions(-) create mode 100644 Source/Applications/Shell/Applets/cat.cpp create mode 100644 Source/Applications/Shell/Applets/free.cpp create mode 100644 Source/Applications/Shell/Applets/halt.cpp create mode 100644 Source/Applications/Shell/Applets/ls.cpp create mode 100644 Source/Applications/Shell/Applets/reboot.cpp delete mode 100644 Source/Applications/Shell/Applets/rot13.cpp create mode 100644 Source/Applications/Shell/Applets/uptime.cpp (limited to 'Source') diff --git a/Source/Applications/Shell/Applets/cat.cpp b/Source/Applications/Shell/Applets/cat.cpp new file mode 100644 index 0000000..169226e --- /dev/null +++ b/Source/Applications/Shell/Applets/cat.cpp @@ -0,0 +1,34 @@ +#include + +class rot13 : public StreamApp { + public: + rot13() : StreamApp("cat", "Concatenate some input files") { + addFlag("r", "rot13", "Apply a ROT13 encryption to the output", FT_BOOL, ""); + } + int run(); +}; + +APP(rot13); + +int rot13::run() { + while (!in->eof()) { + String s = in->get(); + if (in->eof() && s.empty()) break; + if (bFlag("rot13")) { + for (u32int i = 0; i < s.size(); i++) { + WChar &c = s[i]; + if (c >= WChar('A') and c <= WChar('Z')) { + c += 13; + if (c > WChar('Z')) c -= 26; + } + if (c >= WChar('a') and c <= WChar('z')) { + c += 13; + if (c > WChar('z')) c -= 26; + } + } + } + *out << s << ENDL; + } + return 0; +} + diff --git a/Source/Applications/Shell/Applets/free.cpp b/Source/Applications/Shell/Applets/free.cpp new file mode 100644 index 0000000..3217574 --- /dev/null +++ b/Source/Applications/Shell/Applets/free.cpp @@ -0,0 +1,12 @@ +#include +#include + +class free : public ShellApp { + public: + free() : ShellApp("free", "Get the amount of system free RAM") {} + int run() { + outvt << "Free RAM: " << (s64int)Sys::freeRam() << " Kio of " << (s64int)Sys::totalRam() << " Kio\n"; + } +}; + +APP(free); diff --git a/Source/Applications/Shell/Applets/halt.cpp b/Source/Applications/Shell/Applets/halt.cpp new file mode 100644 index 0000000..d7dedef --- /dev/null +++ b/Source/Applications/Shell/Applets/halt.cpp @@ -0,0 +1,13 @@ +#include +#include + +class halt : public ShellApp { + public: + halt() : ShellApp("halt", "Halt the system") {} + int run() { + outvt << "Halting system...\n"; + Sys::halt(); + } +}; + +APP(halt); diff --git a/Source/Applications/Shell/Applets/ls.cpp b/Source/Applications/Shell/Applets/ls.cpp new file mode 100644 index 0000000..3d05de4 --- /dev/null +++ b/Source/Applications/Shell/Applets/ls.cpp @@ -0,0 +1,95 @@ +#include +#include + +#define DIR_COLOR 1 +#define FILE_COLOR 2 +#define NORMAL_COLOR 7 + +class ls : public ShellApp { + public: + ls() : ShellApp("ls", "List the content of a directory") { + addFlag("l", "long", "Use long output", FT_BOOL, ""); + } + int run(); + void doLs(FSNode n); +}; + +int ls::run() { + FSNode cwd = FS::cwdNode(); + if (args.size() == 0) { + doLs(cwd); + } else { + for (u32int i = 0; i < args.size(); i++) { + FSNode n = FS::find(args[i], cwd); + if (!n.valid()) { + outvt << "No such directory : " << args[1] << ENDL; + } else if (n.type() != NT_DIRECTORY) { + outvt << "Not a directory : " << args[1] << ENDL; + } else { + if (args.size() > 1) outvt << n.path() << ":\n"; + doLs(n); + if (args.size() > 1 and i != args.size() - 1) outvt << ENDL; + } + } + } + return 0; +} + +void ls::doLs(FSNode n) { + if (!n.valid()) { + outvt << "Invalid node...\n"; + return; + } + Vector elements; int maxLength = 0; + for (u32int i = 0; i < n.getLength(); i++) { + FSNode c = n.getChild(i); + if (!n.valid()) { + outvt << "[inacessible file]\n"; + continue; + } + if (bFlag("long")) { + String perm = "rwxrwxrwx"; + u32int v = c.getPerm(); + for (u32int i = 0; i < 9; i++) { + if (((v >> i) & 1) == 0) perm[8 - i] = "-"; + } + if (c.type() == NT_FILE) { + outvt << " FILE " << perm << " " << c.getName(); + outvt << MVT::setcsrcol(35) << (s32int)c.getLength() << " bytes.\n"; + } else if (c.type() == NT_DIRECTORY) { + outvt << " DIR " << perm << " " << c.getName() << "/"; + outvt << MVT::setcsrcol(35) << (s32int)c.getLength() << " items.\n"; + } + } else { + String s = c.getName(); + if (c.type() == NT_DIRECTORY) s += "/"; + if (s.size() > maxLength) maxLength = s.size(); + elements.push(s); + } + } + if (!bFlag("long")) { + int nent; + bool boxed = outvt.isBoxed(); + if (!boxed) { + nent = 1; + } else { + nent = outvt.width() / (maxLength + 2); + } + for (int i = 0, e = 0; i < elements.size(); i++, e++) { + if (e >= nent) { + e = 0; + outvt << ENDL; + } + if (boxed) outvt << MVT::setcsrcol(e * (maxLength + 2)); + if (elements[i][elements[i].size() - 1] == WChar("/")) { + outvt << MVT::setfgcolor(DIR_COLOR); + } else { + outvt << MVT::setfgcolor(FILE_COLOR); + } + outvt << elements[i] << MVT::setfgcolor(NORMAL_COLOR); + } + outvt << ENDL; + } +} + +APP(ls); diff --git a/Source/Applications/Shell/Applets/reboot.cpp b/Source/Applications/Shell/Applets/reboot.cpp new file mode 100644 index 0000000..de97fe6 --- /dev/null +++ b/Source/Applications/Shell/Applets/reboot.cpp @@ -0,0 +1,13 @@ +#include +#include + +class reboot : public ShellApp { + public: + reboot() : ShellApp("reboot", "Reboot the system") {} + int run() { + outvt << "Reboot system...\n"; + Sys::reboot(); + } +}; + +APP(reboot); diff --git a/Source/Applications/Shell/Applets/rot13.cpp b/Source/Applications/Shell/Applets/rot13.cpp deleted file mode 100644 index e5638b8..0000000 --- a/Source/Applications/Shell/Applets/rot13.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include - -class rot13 : public StreamApp { - public: - rot13() : StreamApp("rot13", "Cat a file, but ROT13 it") {} - int run(); -}; - -APP(rot13); - -int rot13::run() { - while (!in->eof()) { - String s = in->get(); - if (in->eof() && s.empty()) break; - for (u32int i = 0; i < s.size(); i++) { - WChar &c = s[i]; - if (c >= WChar('A') and c <= WChar('Z')) { - c += 13; - if (c > WChar('Z')) c -= 26; - } - if (c >= WChar('a') and c <= WChar('z')) { - c += 13; - if (c > WChar('z')) c -= 26; - } - } - *out << s << ENDL; - } - return 0; -} - diff --git a/Source/Applications/Shell/Applets/uptime.cpp b/Source/Applications/Shell/Applets/uptime.cpp new file mode 100644 index 0000000..2264fdc --- /dev/null +++ b/Source/Applications/Shell/Applets/uptime.cpp @@ -0,0 +1,26 @@ +#include +#include + +class uptime : public ShellApp { + public: + uptime() : ShellApp("uptime", "Get the system's uptime") { + addFlag("u", "unformatted", "Show raw number of seconds", FT_BOOL, ""); + } + int run() { + if (bFlag("unformatted")) { + outvt << (s64int)Sys::uptime() << ENDL; + } else { + u64int secs = Sys::uptime(); + u64int mins = secs / 60; secs = secs % 60; + u64int hours = mins / 60; mins = mins % 60; + u64int days = hours / 24; hours = hours % 24; + outvt << "Uptime: "; + if (days > 0) outvt << (s64int)days << "d, "; + if (hours > 0) outvt << (s64int)hours << "h, "; + if (mins > 0) outvt << (s64int)mins << "m, "; + outvt << (s64int)secs << "s.\n"; + } + } +}; + +APP(uptime); diff --git a/Source/Applications/Shell/Makefile b/Source/Applications/Shell/Makefile index 4efe01e..1bce0f4 100644 --- a/Source/Applications/Shell/Makefile +++ b/Source/Applications/Shell/Makefile @@ -10,7 +10,7 @@ Objects = Shell.class.o \ Shell-fs.class.o OutFile = Shell -Applets = Applets/rot13 +Applets = Applets/cat Applets/halt Applets/reboot Applets/uptime Applets/free Applets/ls all: $(OutFile) $(Applets) echo "* Done with $(OutFile)." diff --git a/Source/Applications/Shell/Shell-fs.class.cpp b/Source/Applications/Shell/Shell-fs.class.cpp index 23af339..bb1990d 100644 --- a/Source/Applications/Shell/Shell-fs.class.cpp +++ b/Source/Applications/Shell/Shell-fs.class.cpp @@ -2,41 +2,6 @@ #include #include -void Shell::ls(Vector& args) { - FSNode d = cwd; - if (args.size() == 2) { - FSNode n = FS::find(args[1], cwd); - d = FSNode(0); - if (!n.valid()) - outvt << "No such directory : " << args[1] << "\n"; - else if (n.type() != NT_DIRECTORY) - outvt << "Not a directory : " << args[1] << "\n"; - else - d = n; - } - if (d.valid()) outvt << "Contents of directory " << d.path() << " :\n"; - if (!d.valid()) return; - for (u32int i = 0; i < d.getLength(); i++) { - FSNode n = d.getChild(i); - if (!n.valid()) { - outvt << " [inacessible file]\n"; //This is a file we are not supposed to be able to read - continue; - } - String perm = "rwxrwxrwx"; - u32int p = n.getPerm(); - for (u32int i = 0; i < 9; i++) { - if (((p >> i) & 1) == 0) perm[8 - i] = "-"; - } - if (n.type() == NT_FILE) { - outvt << " FILE " << perm << " " << n.getName(); - outvt << MVT::setcsrcol(35) << (s32int)n.getLength() << " bytes.\n"; - } else if (n.type() == NT_DIRECTORY) { - outvt << " DIR " << perm << " " << n.getName() << "/"; - outvt << MVT::setcsrcol(35) << (s32int)n.getLength() << " items.\n"; - } - } -} - void Shell::cd(Vector& args) { if (args.size() != 2) { outvt << "Invalid argument count.\n"; @@ -75,21 +40,6 @@ void Shell::mkdir(Vector& args) { } } -void Shell::cat(Vector& args) { - if (args.size() == 1) outvt << "Meow.\n"; - for (u32int i = 1; i < args.size(); i++) { - TextFile f(args[i], FM_READ, cwd); - if (f.valid() && f.validOpened()) { - while (!f.eof()) { - outvt << f.readLine() << "\n"; - } - f.close(); - } else { - outvt << "Error while reading from file " << args[i] << "\n"; - } - } -} - void Shell::wf(Vector& args) { if (args.size() == 1) { outvt << "No file to write !\n"; @@ -113,17 +63,9 @@ void Shell::run(Vector& args) { if (args.size() == 1) { outvt << "Nothing to run...\n"; } else { - Process p = Process::run(args[1]); - if (p.valid()) { - p.setInVT(invt); - p.setOutVT(outvt); - for (u32int i = 2; i < args.size(); i++) { - p.pushArg(args[i]); - } - p.start(); - s32int v = p.wait(); - outvt << "Return value : " << (s64int)v << "\n"; - } else { + Vector appargs; + for (u32int i = 1; i < args.size(); i++) appargs.push(args[i]); + if (!appRun(args[1], appargs)) { outvt << "Error while launching process.\n"; } } diff --git a/Source/Applications/Shell/Shell.class.cpp b/Source/Applications/Shell/Shell.class.cpp index 4283b30..4bc8e11 100644 --- a/Source/Applications/Shell/Shell.class.cpp +++ b/Source/Applications/Shell/Shell.class.cpp @@ -7,26 +7,40 @@ APP(Shell); Shell::Shell() : ShellApp("Shell.app", "The Melon command line interpreter"), cwd(FS::cwdNode()) { } +void Shell::setupVars() { + shell_var_t tmp; + tmp.readonly = true; + tmp.value = String::number(pr.getUid()); + m_vars.set("UID", tmp); + tmp.value = String::number(pr.getPid()); + m_vars.set("PID", tmp); + tmp.value = "/"; + m_vars.set("CWD", tmp); +} + int Shell::run() { struct { //Command list String name; void (Shell::*cmd)(Vector&); } commands[] = { - {"ls", &Shell::ls}, {"cd", &Shell::cd}, {"pwd", &Shell::pwd}, {"rm", &Shell::rm}, {"mkdir", &Shell::mkdir}, - {"cat", &Shell::cat}, {"wf", &Shell::wf}, {"run", &Shell::run}, {"", 0} }; + setupVars(); + cwd = FS::cwdNode(); while (1) { - outvt << "{" << cwd.getName() << "}: " << FLUSH; + outvt << MVT::setfgcolor(PROMPTS_COLOR) << "{" << MVT::setfgcolor(PROMPTV_COLOR) << cwd.getName() << + MVT::setfgcolor(PROMPTS_COLOR) << "}: " << MVT::setfgcolor(ENTRY_COLOR) << FLUSH; + m_vars["CWD"].value = cwd.path(); String s = invt.get(); + outvt << MVT::setfgcolor(NORMAL_COLOR) << FLUSH; if (s.contains(EOF)) return 0; if (s.empty()) continue; while (s[0] == WChar(" ") or s[0] == WChar("\t")) { @@ -52,26 +66,32 @@ int Shell::run() { } } + for (u32int i = 0; i < cmd.size(); i++) { + if (cmd[i][0] == WChar("$")) { + String k = cmd[i].substr(1); + if (m_vars.has(k)) { + cmd[i] = m_vars[k].value; + } else { + outvt << "Unknown variable : " << k << ENDL; + } + } + } + //Run command if (cmd[0] == "exit") { if (cmd.size() == 1) return 0; return cmd[1].toInt(); - } else if (cmd[0] == "halt") { - Sys::halt(); - outvt << "Something went wrong.\n"; - } else if (cmd[0] == "reboot") { - Sys::reboot(); - outvt << "Something went wrong.\n"; - } else if (cmd[0] == "uptime") { - outvt << "Uptime : " << (s64int)Sys::uptime() << "s\n"; - } else if (cmd[0] == "free") { - outvt << "Free RAM : " << (s64int)Sys::freeRam() << " Kio of " << (s64int)Sys::totalRam() << " Kio\n"; - } else if (cmd[0] == "uid") { - outvt << "User ID : " << (s64int)(pr.getUid()) << "\n"; } else if (cmd[0] == "help") { - while (cmd.size() > 1) cmd.pop(); - cmd.push("/Applications/Shell/Help.txt"); - cat(cmd); + Vector args; + args.push("cat"); + args.push("/Applications/Shell/Help.txt"); + appRun("cat", args); + } else if (cmd[0] == "echo") { + for (u32int i = 1; i < cmd.size(); i++) { + if (i > 1) outvt << " "; + outvt << cmd[i]; + } + outvt << ENDL; } else { u32int i = 0; bool found = false; @@ -87,9 +107,28 @@ int Shell::run() { } i++; } - if (!found) outvt << "Unknown command : " << cmd[0] << "\n"; + if (!found) { + if (!appRun(cmd[0], cmd)) + outvt << "Unknown command : " << cmd[0] << "\n"; + } } } } + +bool Shell::appRun(const String& app, Vector& args) { + Process p = Process::run(app); + if (p.valid()) { + p.setInVT(invt); + p.setOutVT(outvt); + for (u32int i = 1; i < args.size(); i++) { + p.pushArg(args[i]); + } + p.start(); + s32int v = p.wait(); + outvt << "Return value : " << (s64int)v << ENDL; + return true; + } + return false; +} diff --git a/Source/Applications/Shell/Shell.class.h b/Source/Applications/Shell/Shell.class.h index 7c0c324..94a6c2a 100644 --- a/Source/Applications/Shell/Shell.class.h +++ b/Source/Applications/Shell/Shell.class.h @@ -4,10 +4,25 @@ #include #include #include +#include #include +#define PROMPTS_COLOR 1 +#define PROMPTV_COLOR 9 +#define ENTRY_COLOR 6 +#define NORMAL_COLOR 7 + +struct shell_var_t { + bool readonly; + String value; +}; + class Shell : public ShellApp { + Map m_vars; + + void setupVars(); + public: Shell(); @@ -15,12 +30,12 @@ class Shell : public ShellApp { FSNode cwd; - void ls(Vector& args); + bool appRun(const String& name, Vector& args); + void cd(Vector& args); void pwd(Vector& args); void rm(Vector& args); void mkdir(Vector& args); - void cat(Vector& args); void wf(Vector& args); void run(Vector& args); }; diff --git a/Source/Kernel/VTManager/SimpleVT.class.h b/Source/Kernel/VTManager/SimpleVT.class.h index 645e4c2..9c5657e 100644 --- a/Source/Kernel/VTManager/SimpleVT.class.h +++ b/Source/Kernel/VTManager/SimpleVT.class.h @@ -3,7 +3,13 @@ #include +namespace VT { + void redrawScreen(); +} + class SimpleVT : public VirtualTerminal { + friend void VT::redrawScreen(); + protected: vtchr* m_buff; u32int m_rows, m_cols; diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp index ddb4e2c..125d420 100644 --- a/Source/Library/Common/BasicString.class.cpp +++ b/Source/Library/Common/BasicString.class.cpp @@ -183,3 +183,12 @@ BasicString BasicString::substr(s32int start, s32int size) { memcpy((u8int*)ret.m_string, (u8int*)(&m_string[start]), size * sizeof(T)); return ret; } + +template +bool BasicString::operator<(const BasicString& other) const { + for (u32int i = 0; i < m_length && i < other.m_length; i++) { + if (m_string[i] < other.m_string[i]) return true; + } + if (m_length < other.m_length) return true; + return false; +} diff --git a/Source/Library/Common/BasicString.class.h b/Source/Library/Common/BasicString.class.h index 03d82c1..553c331 100644 --- a/Source/Library/Common/BasicString.class.h +++ b/Source/Library/Common/BasicString.class.h @@ -28,6 +28,9 @@ class BasicString { bool operator== (const BasicString &other) const { return compare(other); } bool operator!= (const BasicString &other) const { return !compare(other); } + bool operator<(const BasicString& other) const; + bool operator>(const BasicString& other) const { return (other < *this); } + BasicString& append(const BasicString &other); BasicString& append(const T* string, u32int length); BasicString& append(const T other); diff --git a/Source/Library/Common/Map.class.h b/Source/Library/Common/Map.class.h index 1270752..3428012 100644 --- a/Source/Library/Common/Map.class.h +++ b/Source/Library/Common/Map.class.h @@ -20,22 +20,19 @@ class Map { item_t* find(const K& key, item_t* start) { if (start == 0) return 0; if (start->key == key) return start; - if (start->key > key) return find(key, start->prev); - if (start->key < key) return find(key, start->next); + if (key < start->key) return find(key, start->prev); + else return find(key, start->next); return 0; } item_t* insert(const K& key, const V& value, item_t* start) { if (start == 0) return new item_t(key, value); - if (start->key == key) return 0; - if (start->key > key) { + if (start->key == key) return start; + if (key < start->key) { start->prev = insert(key, value, start->prev); - return start; - } - if (start->key < key) { + } else { start->next = insert(key, value, start->next); - return start; } - return 0; + return start; } public: -- cgit v1.2.3