summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rwxr-xr-xCopyToFDD.sh14
-rw-r--r--Source/Applications/Demos/GOL.cpp14
-rw-r--r--Source/Applications/Demos/cxxdemo.cpp14
-rw-r--r--Source/Applications/PaperWork/Makefile2
-rw-r--r--Source/Applications/PaperWork/PaperWork.cpp (renamed from Source/Applications/PaperWork/main.cpp)31
-rw-r--r--Source/Applications/Shell/Makefile5
-rw-r--r--Source/Applications/Shell/Shell-fs.class.cpp (renamed from Source/Applications/Shell/Shell-fs.ns.cpp)22
-rw-r--r--Source/Applications/Shell/Shell.class.cpp (renamed from Source/Applications/Shell/Shell.ns.cpp)34
-rw-r--r--Source/Applications/Shell/Shell.class.h28
-rw-r--r--Source/Applications/Shell/Shell.ns.h18
-rw-r--r--Source/Kernel/Devices/Display/VESADisplay.class.cpp19
-rw-r--r--Source/Kernel/Makefile2
-rw-r--r--Source/Kernel/Shell/KernelShell-sys.class.cpp2
-rw-r--r--Source/Library/Common/CMem.ns.cpp14
-rw-r--r--Source/Library/Common/CMem.ns.h2
-rw-r--r--Source/Library/Common/String.class.cpp1
-rw-r--r--Source/Library/Common/String.class.h1
-rw-r--r--Source/Library/Common/cppsupport.wtf.cpp2
-rw-r--r--Source/Library/Makefile1
-rw-r--r--Source/Library/Userland/App/Application.proto.h40
-rw-r--r--Source/Library/Userland/App/ShellApp.proto.cpp139
-rw-r--r--Source/Library/Userland/App/ShellApp.proto.h39
-rw-r--r--Source/Library/Userland/Binding/VirtualTerminal.class.h2
-rw-r--r--Source/Library/Userland/Start.cpp40
25 files changed, 374 insertions, 114 deletions
diff --git a/.gitignore b/.gitignore
index 4246a36..7562cf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@
Init.rfs
Source/Kernel/Map.txt
Source/Kernel/Melon.ke
+Ports
+Ports/*
diff --git a/CopyToFDD.sh b/CopyToFDD.sh
index f5d93d6..7b8459a 100755
--- a/CopyToFDD.sh
+++ b/CopyToFDD.sh
@@ -7,10 +7,14 @@ cp Grub-menu-fdd.cfg Mount/boot/menu.cfg
# Create directories
mkdir Mount/{System,Applications,Volumes}
-mkdir Mount/Applications/Shell
+mkdir Mount/Applications/{Shell,Demos}
mkdir Mount/System/{Applications,Logs,Configuration}
mkdir Mount/Volumes/{HDD,InitRFS}
+# Copy kernel and ramfs
+cp Source/Kernel/Melon.ke Mount/System
+cp Init.rfs Mount/System
+
# Copy system files
cp Source/Kernel/Ressources/Configuration/* Mount/System/Configuration
cp Source/Applications/PaperWork/PaperWork Mount/System/Applications/PaperWork.app
@@ -21,12 +25,8 @@ echo "/Volumes/InitRFS:ramfs:0" > Mount/System/Configuration/Mount
echo "/Volumes/HDD:block.ata:0:1" >> Mount/System/Configuration/Mount
# Copy demo apps
-cp Source/Applications/Demos/GOL Mount/Apps/GOL.app
-cp Source/Applications/Demos/asmdemo Mount/Apps/ASM.dem
-
-# Copy kernel and ramfs
-cp Source/Kernel/Melon.ke Mount/System
-cp Init.rfs Mount/System
+cp Source/Applications/Demos/GOL Mount/Applications/Demos/GOL.app
+cp Source/Applications/Demos/asmdemo Mount/Applications/Demos/ASM.dem
#echo "*** Launching a BASH shell, if you want to do any maintenance ***"
#bash || exit 0
diff --git a/Source/Applications/Demos/GOL.cpp b/Source/Applications/Demos/GOL.cpp
index e6da3a6..675c159 100644
--- a/Source/Applications/Demos/GOL.cpp
+++ b/Source/Applications/Demos/GOL.cpp
@@ -1,10 +1,18 @@
-#include <Binding/VirtualTerminal.class.h>
#include <Binding/Thread.class.h>
-#include <String.class.h>
#include <ByteArray.class.h>
#include <Rand.ns.h>
-int main(Vector<String> args) {
+#include <App/ShellApp.proto.h>
+
+class GOL : public ShellApp {
+ public:
+ GOL() : ShellApp("GOL.app", "Melon's Game of Life simulator \\o/") {}
+ int run();
+};
+
+APP(GOL);
+
+int GOL::run() {
if (!outvt.isBoxed()) {
outvt << "Error : cannot display GOL on a non-boxed terminal.\n";
return 1;
diff --git a/Source/Applications/Demos/cxxdemo.cpp b/Source/Applications/Demos/cxxdemo.cpp
index 3d452e7..36cfd27 100644
--- a/Source/Applications/Demos/cxxdemo.cpp
+++ b/Source/Applications/Demos/cxxdemo.cpp
@@ -1,10 +1,18 @@
#include <Syscall/Syscall.wtf.h>
-#include <String.class.h>
-#include <Binding/VirtualTerminal.class.h>
#include <Binding/Thread.class.h>
#include <Binding/File.class.h>
-int main(const Vector<String>& args) {
+#include <App/ShellApp.proto.h>
+
+class CPPDemo : public ShellApp {
+ public:
+ CPPDemo() : ShellApp("CPPDemo.app", "A demo application using the C++ Melon framework") {}
+ int run();
+};
+
+APP(CPPDemo);
+
+int CPPDemo::run() {
outvt << "Enter some text plz : ";
String s = invt.readLine();
outvt << s;
diff --git a/Source/Applications/PaperWork/Makefile b/Source/Applications/PaperWork/Makefile
index fe8d564..d3203cf 100644
--- a/Source/Applications/PaperWork/Makefile
+++ b/Source/Applications/PaperWork/Makefile
@@ -6,7 +6,7 @@ CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I .
LD = ld
LDFLAGS = -T ../../Library/Link.ld -L ../../Library
-Objects = main.o
+Objects = PaperWork.o
OutFile = PaperWork
all: $(OutFile)
diff --git a/Source/Applications/PaperWork/main.cpp b/Source/Applications/PaperWork/PaperWork.cpp
index 2fb40df..4f9cb0e 100644
--- a/Source/Applications/PaperWork/main.cpp
+++ b/Source/Applications/PaperWork/PaperWork.cpp
@@ -1,17 +1,22 @@
-#include <Binding/Process.class.h>
-#include <String.class.h>
+#include <App/ShellApp.proto.h>
#define DEFAULT_SHELL "/Applications/Shell/Shell.app"
-int main(Vector<String> args) {
- String act = "init";
- if (args.size() == 2) {
- if (args[1] == "login") {
- act = "login";
- } else if (args[1] == "init") {
- act = "init";
- }
+class PaperWork : public ShellApp {
+ public:
+ PaperWork() : ShellApp("PaperWork.app", "Melon's init/login manager") {
+ addFlag("s", "shell", "Define the default shell to launch", FT_STR, DEFAULT_SHELL);
+ addFlag("l", "login", "Act as a login manager");
+ addFlag("i", "init", "Act as a init manager", FT_BOOL, "on");
}
+ int run();
+};
+
+APP(PaperWork);
+
+int PaperWork::run() {
+ String act = "init";
+ if (bFlag("login")) act = "login";
if (act == "init") {
while (1) {
@@ -19,7 +24,7 @@ int main(Vector<String> args) {
if (p.valid()) {
p.setInVT(invt);
p.setOutVT(outvt);
- p.pushArg("login");
+ p.pushArg("--login");
p.start();
p.wait();
} else {
@@ -38,9 +43,9 @@ int main(Vector<String> args) {
outvt << "Authentication failed.\n\n";
continue;
}
- outvt << "What shell to run [" << DEFAULT_SHELL << "]? ";
+ outvt << "What shell to run [" << sFlag("shell") << "]? ";
String sh = invt.readLine();
- if (sh == "") sh = DEFAULT_SHELL;
+ if (sh == "") sh = sFlag("shell");
Process p = Process::run(sh);
if (p.valid()) {
p.setInVT(invt);
diff --git a/Source/Applications/Shell/Makefile b/Source/Applications/Shell/Makefile
index bf81af6..d546a15 100644
--- a/Source/Applications/Shell/Makefile
+++ b/Source/Applications/Shell/Makefile
@@ -6,9 +6,8 @@ CXXFLAGS = -nostartfiles -nostdlib -ffreestanding -fno-exceptions -fno-rtti -I .
LD = ld
LDFLAGS = -T ../../Library/Link.ld -L ../../Library
-Objects = main.o \
- Shell.ns.o \
- Shell-fs.ns.o
+Objects = Shell.class.o \
+ Shell-fs.class.o
OutFile = Shell
all: $(OutFile)
diff --git a/Source/Applications/Shell/Shell-fs.ns.cpp b/Source/Applications/Shell/Shell-fs.class.cpp
index 0b51299..150b877 100644
--- a/Source/Applications/Shell/Shell-fs.ns.cpp
+++ b/Source/Applications/Shell/Shell-fs.class.cpp
@@ -1,10 +1,8 @@
-#include "Shell.ns.h"
+#include "Shell.class.h"
#include <TextFile.class.h>
#include <Binding/Process.class.h>
-namespace Shell {
-
-void ls(Vector<String>& args) {
+void Shell::ls(Vector<String>& args) {
FSNode d = cwd;
if (args.size() == 2) {
FSNode n = FS::find(args[1], cwd);
@@ -41,7 +39,7 @@ void ls(Vector<String>& args) {
}
}
-void cd(Vector<String>& args) {
+void Shell::cd(Vector<String>& args) {
if (args.size() != 2) {
outvt << "Invalid argument count.\n";
} else {
@@ -57,11 +55,11 @@ void cd(Vector<String>& args) {
}
}
-void pwd(Vector<String>& args) {
+void Shell::pwd(Vector<String>& args) {
outvt << "Current directory : " << cwd.path() << "\n";
}
-void rm(Vector<String>& args) {
+void Shell::rm(Vector<String>& args) {
if (args.size() == 1) outvt << "No file to remove.\n";
for (u32int i = 1; i < args.size(); i++) {
if (!FS::find(args[i], cwd).remove()) {
@@ -70,7 +68,7 @@ void rm(Vector<String>& args) {
}
}
-void mkdir(Vector<String>& args) {
+void Shell::mkdir(Vector<String>& args) {
if (args.size() == 1) outvt << "No directory to create.\n";
for (u32int i = 1; i < args.size(); i++) {
if (!FS::mkdir(args[i], cwd).valid()) {
@@ -79,7 +77,7 @@ void mkdir(Vector<String>& args) {
}
}
-void cat(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);
@@ -94,7 +92,7 @@ void cat(Vector<String>& args) {
}
}
-void wf(Vector<String>& args) {
+void Shell::wf(Vector<String>& args) {
if (args.size() == 1) {
outvt << "No file to write !\n";
} else {
@@ -113,7 +111,7 @@ void wf(Vector<String>& args) {
}
}
-void run(Vector<String>& args) {
+void Shell::run(Vector<String>& args) {
if (args.size() == 1) {
outvt << "Nothing to run...\n";
} else {
@@ -132,5 +130,3 @@ void run(Vector<String>& args) {
}
}
}
-
-}
diff --git a/Source/Applications/Shell/Shell.ns.cpp b/Source/Applications/Shell/Shell.class.cpp
index 56a6b5f..3d406c8 100644
--- a/Source/Applications/Shell/Shell.ns.cpp
+++ b/Source/Applications/Shell/Shell.class.cpp
@@ -1,25 +1,25 @@
-#include "Shell.ns.h"
+#include "Shell.class.h"
#include <Binding/Sys.ns.h>
#include <Binding/Process.class.h>
-namespace Shell {
-
-FSNode cwd(0);
+APP(Shell);
+Shell::Shell() : ShellApp("Shell.app", "The Melon command line interpreter"), cwd(FS::cwdNode()) {
+}
-u32int run() {
+int Shell::run() {
struct { //Command list
String name;
- void (*cmd)(Vector<String>&);
+ void (Shell::*cmd)(Vector<String>&);
} commands[] = {
- {"ls", ls},
- {"cd", cd},
- {"pwd", pwd},
- {"rm", rm},
- {"mkdir", mkdir},
- {"cat", cat},
- {"wf", wf},
- {"run", run},
+ {"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}
};
@@ -66,7 +66,7 @@ u32int run() {
} 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)(Process::get().getUid()) << "\n";
+ outvt << "User ID : " << (s64int)(pr.getUid()) << "\n";
} else if (cmd[0] == "help") {
while (cmd.size() > 1) cmd.pop();
cmd.push("/Applications/Shell/Help.txt");
@@ -80,7 +80,7 @@ u32int run() {
if (commands[i].cmd == 0) {
outvt << "Not implemented yet.\n";
} else {
- commands[i].cmd(cmd);
+ (this->*(commands[i].cmd))(cmd);
}
break;
}
@@ -91,6 +91,4 @@ u32int run() {
}
}
-}
-
diff --git a/Source/Applications/Shell/Shell.class.h b/Source/Applications/Shell/Shell.class.h
new file mode 100644
index 0000000..7c0c324
--- /dev/null
+++ b/Source/Applications/Shell/Shell.class.h
@@ -0,0 +1,28 @@
+#ifndef DEF_SHELL_CLASS_H
+#define DEF_SHELL_CLASS_H
+
+#include <Binding/VirtualTerminal.class.h>
+#include <Binding/FSNode.class.h>
+#include <String.class.h>
+
+#include <App/ShellApp.proto.h>
+
+class Shell : public ShellApp {
+ public:
+ Shell();
+
+ int run();
+
+ FSNode cwd;
+
+ void ls(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);
+};
+
+#endif
diff --git a/Source/Applications/Shell/Shell.ns.h b/Source/Applications/Shell/Shell.ns.h
deleted file mode 100644
index b2dd587..0000000
--- a/Source/Applications/Shell/Shell.ns.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <Binding/VirtualTerminal.class.h>
-#include <Binding/FSNode.class.h>
-#include <String.class.h>
-
-namespace Shell {
- u32int run();
-
- extern FSNode cwd;
-
- extern void ls(Vector<String>& args);
- extern void cd(Vector<String>& args);
- extern void pwd(Vector<String>& args);
- extern void rm(Vector<String>& args);
- extern void mkdir(Vector<String>& args);
- extern void cat(Vector<String>& args);
- extern void wf(Vector<String>& args);
- extern void run(Vector<String>& args);
-}
diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.cpp b/Source/Kernel/Devices/Display/VESADisplay.class.cpp
index f882d5b..d4aee07 100644
--- a/Source/Kernel/Devices/Display/VESADisplay.class.cpp
+++ b/Source/Kernel/Devices/Display/VESADisplay.class.cpp
@@ -245,7 +245,24 @@ void VESADisplay::drawChar(u16int line, u16int col, WChar c, u8int color) {
fgcolor = color & 0xF;
bgcolor = (color >> 4) & 0xF;
}
-
+
+ if (c == WChar(" ")) {
+ u8int* p = memPos(sx, sy);
+ for (int y = 0; y < C_FONT_HEIGHT; y++) {
+ if (m_pixWidth == 1) memset(p, bgcolor, 9);
+ if (m_pixWidth == 2) memsetw((u16int*)p, bgcolor, 9);
+ if (m_pixWidth == 3) {
+ for (int i = 0; i < 9; i++) {
+ p[0] = (bgcolor >> 16);
+ p[1] = (bgcolor >> 8);
+ p[2] = (bgcolor);
+ p += 3;
+ }
+ }
+ p += m_currMode.pitch;
+ }
+ return;
+ }
int y = 0;
for (u8int* p = memPos(sx, sy); p < memPos(sx, sy + C_FONT_HEIGHT); p += m_currMode.pitch) {
diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile
index 660017a..0f244d5 100644
--- a/Source/Kernel/Makefile
+++ b/Source/Kernel/Makefile
@@ -5,7 +5,7 @@ CXX = g++
LD = ld
LDFLAGS = -T Link.ld -Map Map.txt --oformat=elf32-i386
CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -I .
-CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -I ../Library/Interface -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL
+CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -I ../Library/Interface -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL -O2
ASM = nasm
ASMFLAGS = -f elf
diff --git a/Source/Kernel/Shell/KernelShell-sys.class.cpp b/Source/Kernel/Shell/KernelShell-sys.class.cpp
index da5378b..85ba207 100644
--- a/Source/Kernel/Shell/KernelShell-sys.class.cpp
+++ b/Source/Kernel/Shell/KernelShell-sys.class.cpp
@@ -77,7 +77,7 @@ void KernelShell::mount(Vector<String>& args) {
if (VFS::mount(args[1], m_vt)) *m_vt << "Ok, filesystem mounted.\n";
}
} else {
- *m_vt << "Usage: mount [<device> <mountpoint>\n";
+ *m_vt << "Wrong options. Type 'mount help' for more info.\n";
}
}
diff --git a/Source/Library/Common/CMem.ns.cpp b/Source/Library/Common/CMem.ns.cpp
index 37cdf0c..a4da4d2 100644
--- a/Source/Library/Common/CMem.ns.cpp
+++ b/Source/Library/Common/CMem.ns.cpp
@@ -3,9 +3,17 @@
namespace CMem {
//Standard C functions
-u8int *memcpy(u8int *dest, const u8int *src, int count) {
- for (int i = 0; i < count; i++) {
- dest[i] = src[i];
+u8int *memcpy(u8int *dest, const u8int *src, u32int count) {
+ u32int f = count % 4, n = count / 4;
+ const u32int* s = (u32int*)src;
+ u32int* d = (u32int*)dest;
+ for (u32int i = 0; i < n; i++) {
+ d[i] = s[i];
+ }
+ if (f != 0) {
+ for (u32int i = count - f; i < count; i++) {
+ dest[i] = src[i];
+ }
}
return dest;
}
diff --git a/Source/Library/Common/CMem.ns.h b/Source/Library/Common/CMem.ns.h
index f0c15da..aecddc9 100644
--- a/Source/Library/Common/CMem.ns.h
+++ b/Source/Library/Common/CMem.ns.h
@@ -6,7 +6,7 @@
//This namespace contains basic memory managment functions
namespace CMem {
- u8int *memcpy(u8int *dest, const u8int *src, int count);
+ u8int *memcpy(u8int *dest, const u8int *src, u32int count);
u8int *memset(u8int *dest, u8int val, int count);
u16int *memsetw(u16int *dest, u16int val, int count);
u32int strlen(const char *str);
diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp
index fe851bd..8e958e0 100644
--- a/Source/Library/Common/String.class.cpp
+++ b/Source/Library/Common/String.class.cpp
@@ -195,6 +195,7 @@ String String::substr(s32int start, s32int size) {
if (size == 0) return String();
if (start < 0) start = m_length - start;
if (size == -1) size = m_length - start;
+ if (start + size >= (int)m_length) size = m_length - start;
String ret;
ret.m_string = new WChar[size + 1];
ret.m_length = size;
diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h
index b623fb2..14f07f0 100644
--- a/Source/Library/Common/String.class.h
+++ b/Source/Library/Common/String.class.h
@@ -14,6 +14,7 @@ class String : public BasicString<WChar> {
String(const char* string, u8int encoding = UE_UTF8);
String() : BasicString<WChar>() {}
+ String(WChar c, u32int n = 1) : BasicString<WChar>(c, n) {}
String(const String &other) : BasicString<WChar> (other) {}
void affect(const char* string, u8int encoding = UE_UTF8);
diff --git a/Source/Library/Common/cppsupport.wtf.cpp b/Source/Library/Common/cppsupport.wtf.cpp
index 06ef1b9..59a78fc 100644
--- a/Source/Library/Common/cppsupport.wtf.cpp
+++ b/Source/Library/Common/cppsupport.wtf.cpp
@@ -2,7 +2,7 @@
#include <types.h>
namespace CMem {
- u8int* memcpy(u8int*, const u8int*, int);
+ u8int* memcpy(u8int*, const u8int*, u32int);
};
using namespace CMem;
diff --git a/Source/Library/Makefile b/Source/Library/Makefile
index 5c77c84..b3040d4 100644
--- a/Source/Library/Makefile
+++ b/Source/Library/Makefile
@@ -20,6 +20,7 @@ Objects = Common/WChar.class.uo \
Common/ByteArray.class.uo \
Common/Rand.ns.uo \
Common/cppsupport.wtf.uo \
+ Userland/App/ShellApp.proto.uo \
Userland/Syscall/Syscall.wtf.uo \
Userland/Syscall/RessourceCaller.class.uo \
Userland/Start.uo
diff --git a/Source/Library/Userland/App/Application.proto.h b/Source/Library/Userland/App/Application.proto.h
new file mode 100644
index 0000000..46b0975
--- /dev/null
+++ b/Source/Library/Userland/App/Application.proto.h
@@ -0,0 +1,40 @@
+#ifndef DEF_APPLICATION_PROTO_H
+#define DEF_APPLICATION_PROTO_H
+
+#include <Binding/Process.class.h>
+#include <String.class.h>
+
+extern u32int start_dtors, end_dtors;
+
+#define APP(t) static t the_app; \
+ Application *app = &the_app;
+
+class Application {
+ public:
+ Process pr;
+
+ Application() : pr(Process::get()) {
+ //TODO : add default signal handlers
+ }
+ virtual ~Application() {}
+
+ virtual void init() {} //Do anything that can't be done in the constructor
+ virtual int run() = 0; //Application's main loop
+
+ virtual void doEvents() {
+ //TODO : handle signals (IPC featurs to come)
+ }
+
+ void exit(u32int ret) {
+ //Call static destructors
+ for(u32int * call = &start_dtors; call < &end_dtors; call++) {
+ ((void (*)(void))*call)();
+ }
+ threadFinishedSyscall(ret);
+ }
+};
+
+extern Application *app;
+
+#endif
+
diff --git a/Source/Library/Userland/App/ShellApp.proto.cpp b/Source/Library/Userland/App/ShellApp.proto.cpp
new file mode 100644
index 0000000..a3d9737
--- /dev/null
+++ b/Source/Library/Userland/App/ShellApp.proto.cpp
@@ -0,0 +1,139 @@
+#include "ShellApp.proto.h"
+
+ShellApp::ShellApp(String name, String desc)
+ : Application(), invt(VirtualTerminal::getIn()), outvt(VirtualTerminal::getOut()) {
+ appName = name, appDesc = desc;
+ if (!invt.valid()) exit(1);
+ if (!outvt.valid()) exit(2);
+
+ addFlag("h", "help", "Show this help screen");
+}
+
+void ShellApp::init() {
+ //Parse flags
+ u32int argc = pr.argc();
+ for (u32int i = 0; i < argc; i++) {
+ String arg = pr.argv(i);
+ if (arg == "-") {
+ i++;
+ if (i == argc) {
+ args.push("-");
+ } else {
+ for (; i < argc; i++) args.push(pr.argv(i));
+ }
+ } else if (arg[0] == WChar("-")) {
+ if (arg.substr(0, 5) == "--no-") {
+ bool found = false;
+ for (u32int i = 0; i < flags.size(); i++) {
+ if (flags[i].type == FT_BOOL) {
+ if (arg == String("--no-") + flags[i].lName) {
+ flags[i].boolVal = false;
+ found = true;
+ }
+ }
+ }
+ if (!found) outvt << "Unknown option : " << arg << "\n";
+ } else if (arg.substr(0, 2) == "--") {
+ bool found = false;
+ for (u32int i = 0; i < flags.size(); i++) {
+ if (flags[i].type == FT_BOOL) {
+ if (arg == String("--") + flags[i].lName) {
+ flags[i].boolVal = true;
+ found = true;
+ }
+ } else {
+ if (arg.substr(2, 1 + flags[i].lName.size()) == flags[i].lName + "=") {
+ found = true;
+ flags[i].strVal = arg.substr(3 + flags[i].lName.size(), arg.size());
+ if (flags[i].type == FT_INT) flags[i].intVal = flags[i].strVal.toInt();
+ }
+ }
+ }
+ if (!found) outvt << "Unknown option : " << arg << "\n";
+ } else {
+ for (u32int j = 1; j < arg.size(); j++) {
+ bool found = false;
+ for (u32int k = 0; k < flags.size(); k++) {
+ if (flags[k].sName == arg[j]) {
+ found = true;
+ if (flags[k].type == FT_BOOL) flags[k].boolVal = true;
+ if (flags[k].type == FT_INT) flags[k].intVal = pr.argv(++i).toInt();
+ if (flags[k].type == FT_STR) flags[k].strVal = pr.argv(++i);
+ break;
+ }
+ }
+ if (!found) {
+ outvt << "Unknown option : -" << String(arg[j]) << "\n";
+ exit(-1);
+ }
+ }
+ }
+ } else {
+ args.push(arg);
+ }
+ }
+
+ //Eventually show help screen
+ if (bFlag("help")) {
+ outvt << appName << ": " << appDesc << "\n";
+ outvt << "Usage: \t" << appName << " <flags> [-] <arguments>\n\n";
+ outvt << "Possible flags :\n";
+ for (u32int i = 0; i < flags.size(); i++) {
+ outvt << " --" << flags[i].lName << "\t" << (flags[i].sName != 0 ? "-" : "") << String(flags[i].sName) << "\t";
+ if (flags[i].type == FT_STR) outvt << "Default: " << flags[i].strVal << "\n";
+ if (flags[i].type == FT_INT) outvt << "Default: " << flags[i].intVal << "\n";
+ if (flags[i].type == FT_BOOL) outvt << "Default: " << (flags[i].boolVal && flags[i].lName != "help" ? "on" : "off") << "\n";
+ if (!flags[i].desc.empty()) outvt << "\t" << flags[i].desc << "\n";
+ outvt << "\n";
+ }
+ exit(0);
+ }
+}
+
+//******************** FLAG HANDLING *****************
+
+flag_t *ShellApp::getFlag(String name) {
+ for (u32int i = 0; i < flags.size(); i++) {
+ if (flags[i].lName == name) return &flags[i];
+ }
+ return NULL;
+}
+
+void ShellApp::addFlag(WChar sName, String lName, String desc, int type, String deflt) {
+ if (lName.empty()) return;
+ if (getFlag(lName) != false) return;
+ flag_t temp;
+ temp.sName = sName;
+ temp.lName = lName;
+ temp.type = type;
+ temp.desc = desc;
+ if (type == FT_BOOL) {
+ temp.boolVal = !deflt.empty();
+ } else if (type == FT_STR) {
+ temp.strVal = deflt;
+ } else if (type == FT_INT) {
+ temp.intVal = deflt.toInt();
+ }
+ flags.push(temp);
+}
+
+String ShellApp::sFlag(String name) {
+ flag_t* f = getFlag(name);
+ if (f == 0) return "";
+ if (f->type != FT_STR) return "";
+ return f->strVal;
+}
+
+int ShellApp::iFlag(String name) {
+ flag_t* f = getFlag(name);
+ if (f == 0) return 0;
+ if (f->type != FT_INT) return 0;
+ return f->intVal;
+}
+
+bool ShellApp::bFlag(String name) {
+ flag_t *f = getFlag(name);
+ if (f == 0) return false;
+ if (f->type != FT_BOOL) return false;
+ return f->boolVal;
+}
diff --git a/Source/Library/Userland/App/ShellApp.proto.h b/Source/Library/Userland/App/ShellApp.proto.h
new file mode 100644
index 0000000..5575112
--- /dev/null
+++ b/Source/Library/Userland/App/ShellApp.proto.h
@@ -0,0 +1,39 @@
+#ifndef DEF_SHELLAPP_CLASS_H
+#define DEF_SHELLAPP_CLASS_H
+
+#include <App/Application.proto.h>
+#include <Binding/VirtualTerminal.class.h>
+
+#define FT_BOOL 1
+#define FT_STR 2
+#define FT_INT 3
+
+struct flag_t {
+ WChar sName;
+ String lName, desc;
+ int type;
+ String strVal;
+ int intVal;
+ bool boolVal;
+};
+
+class ShellApp : public Application {
+ public:
+ VirtualTerminal invt, outvt;
+ Vector<String> args;
+ Vector<flag_t> flags;
+ String appName, appDesc;
+ ShellApp(String name, String desc);
+
+ virtual void init();
+
+ //Flag handling
+ flag_t* getFlag(String name);
+ void addFlag(WChar sName, String lName, String desc, int type = FT_BOOL, String deflt = "");
+ String sFlag(String name);
+ int iFlag(String name);
+ bool bFlag(String name);
+};
+
+#endif
+
diff --git a/Source/Library/Userland/Binding/VirtualTerminal.class.h b/Source/Library/Userland/Binding/VirtualTerminal.class.h
index c8a4123..70c6b23 100644
--- a/Source/Library/Userland/Binding/VirtualTerminal.class.h
+++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h
@@ -71,6 +71,4 @@ class VirtualTerminal : public RessourceCaller {
inline VirtualTerminal& operator<<(u32int i) { writeHex(i); return *this; }
};
-extern VirtualTerminal invt, outvt;
-
#endif
diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp
index f1d1771..3f825e9 100644
--- a/Source/Library/Userland/Start.cpp
+++ b/Source/Library/Userland/Start.cpp
@@ -1,46 +1,36 @@
#include <types.h>
#include <Syscall/Syscall.wtf.h>
-#include <Binding/VirtualTerminal.class.h>
-#include <Heap.class.h>
+#include <App/Application.proto.h>
-extern u32int start_ctors, end_ctors, start_dtors, end_dtors;
+#include <Heap.class.h>
-Heap heap;
+extern u32int start_ctors, end_ctors;
-VirtualTerminal invt(0), outvt(0);
+Heap *heap;
int main(const Vector<String>& args);
extern "C" void start() {
- heap.create(0x40000000, 0x00040000, 0x00004000); //Initially create a 256ko heap with 16ko index
+ Heap h;
+ h.create(0x40000000, 0x00040000, 0x00004000); //Initially create a 256ko heap with 16ko index
+ heap = &h;
- //Call static constructors
+ //Call static constructors (this will construct the Application object and get some stuff (arguments, ...))
u32int i = 0;
for(u32int * call = &start_ctors; call < &end_ctors; call++) {
((void (*)(void))*call)();
}
- invt = VirtualTerminal::getIn(); outvt = VirtualTerminal::getOut();
- if (!invt.valid()) threadFinishedSyscall(1);
- if (!outvt.valid()) threadFinishedSyscall(2);
-
- u32int argc = Process::get().argc();
- Vector<String> args(argc);
- for (u32int i = 0; i < argc; i++) args[i] = Process::get().argv(i);
-
- u32int r = main(args);
-
- //Call static destructors
- for(u32int * call = &start_dtors; call < &end_dtors; call++) {
- ((void (*)(void))*call)();
- }
-
- threadFinishedSyscall(r);
+ app->init();
+ app->doEvents();
+ u32int r = app->run();
+ app->doEvents();
+ app->exit(r); //Will call static destructors
}
namespace Mem {
- void* alloc (size_t sz) { return heap.alloc(sz); }
- void free(void* ptr) { heap.free(ptr); }
+ void* alloc (size_t sz) { return heap->alloc(sz); }
+ void free(void* ptr) { heap->free(ptr); }
void* mkXchgSpace (size_t sz) { return alloc(sz); }
}