summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Applications/Shell/Applets/cat.cpp34
-rw-r--r--Source/Applications/Shell/Applets/free.cpp12
-rw-r--r--Source/Applications/Shell/Applets/halt.cpp13
-rw-r--r--Source/Applications/Shell/Applets/ls.cpp95
-rw-r--r--Source/Applications/Shell/Applets/reboot.cpp13
-rw-r--r--Source/Applications/Shell/Applets/rot13.cpp30
-rw-r--r--Source/Applications/Shell/Applets/uptime.cpp26
-rw-r--r--Source/Applications/Shell/Makefile2
-rw-r--r--Source/Applications/Shell/Shell-fs.class.cpp64
-rw-r--r--Source/Applications/Shell/Shell.class.cpp77
-rw-r--r--Source/Applications/Shell/Shell.class.h19
-rw-r--r--Source/Kernel/VTManager/SimpleVT.class.h6
-rw-r--r--Source/Library/Common/BasicString.class.cpp9
-rw-r--r--Source/Library/Common/BasicString.class.h3
-rw-r--r--Source/Library/Common/Map.class.h15
15 files changed, 296 insertions, 122 deletions
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 <App/StreamApp.proto.h>
+
+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 <App/ShellApp.proto.h>
+#include <Binding/Sys.ns.h>
+
+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 <App/ShellApp.proto.h>
+#include <Binding/Sys.ns.h>
+
+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 <App/ShellApp.proto.h>
+#include <Binding/FSNode.class.h>
+
+#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<String> 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 <App/ShellApp.proto.h>
+#include <Binding/Sys.ns.h>
+
+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 <App/StreamApp.proto.h>
-
-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 <App/ShellApp.proto.h>
+#include <Binding/Sys.ns.h>
+
+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 <TextFile.class.h>
#include <Binding/Process.class.h>
-void Shell::ls(Vector<String>& 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<String>& args) {
if (args.size() != 2) {
outvt << "Invalid argument count.\n";
@@ -75,21 +40,6 @@ void Shell::mkdir(Vector<String>& args) {
}
}
-void Shell::cat(Vector<String>& 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<String>& args) {
if (args.size() == 1) {
outvt << "No file to write !\n";
@@ -113,17 +63,9 @@ void Shell::run(Vector<String>& 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<String> 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<String>&);
} 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<String> 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<String>& 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 <Binding/VirtualTerminal.class.h>
#include <Binding/FSNode.class.h>
#include <String.class.h>
+#include <Map.class.h>
#include <App/ShellApp.proto.h>
+#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<String, shell_var_t> m_vars;
+
+ void setupVars();
+
public:
Shell();
@@ -15,12 +30,12 @@ class Shell : public ShellApp {
FSNode cwd;
- void ls(Vector<String>& args);
+ bool appRun(const String& name, Vector<String>& args);
+
void cd(Vector<String>& args);
void pwd(Vector<String>& args);
void rm(Vector<String>& args);
void mkdir(Vector<String>& args);
- void cat(Vector<String>& args);
void wf(Vector<String>& args);
void run(Vector<String>& 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 <VTManager/VirtualTerminal.proto.h>
+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<T> BasicString<T>::substr(s32int start, s32int size) {
memcpy((u8int*)ret.m_string, (u8int*)(&m_string[start]), size * sizeof(T));
return ret;
}
+
+template <typename T>
+bool BasicString<T>::operator<(const BasicString<T>& 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<T> &other) const { return compare(other); }
bool operator!= (const BasicString<T> &other) const { return !compare(other); }
+ bool operator<(const BasicString<T>& other) const;
+ bool operator>(const BasicString<T>& other) const { return (other < *this); }
+
BasicString<T>& append(const BasicString<T> &other);
BasicString<T>& append(const T* string, u32int length);
BasicString<T>& 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: