From 4f9078c0f06e0cf0cb7bb164fc72fb9918c68e6a Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Thu, 17 Dec 2009 11:18:19 +0100 Subject: Added some option handling featurs to the default ShellApp class --- Source/Applications/Demos/GOL.cpp | 2 +- Source/Applications/Demos/cxxdemo.cpp | 2 +- Source/Applications/PaperWork/PaperWork.cpp | 20 ++-- Source/Applications/Shell/Shell.class.cpp | 2 +- Source/Kernel/Shell/KernelShell-sys.class.cpp | 2 +- Source/Library/Common/CMem.ns.cpp | 14 ++- Source/Library/Common/CMem.ns.h | 2 +- Source/Library/Common/String.class.cpp | 1 + Source/Library/Common/String.class.h | 1 + Source/Library/Common/cppsupport.wtf.cpp | 2 +- Source/Library/Makefile | 1 + Source/Library/Userland/App/Application.proto.h | 5 +- Source/Library/Userland/App/ShellApp.proto.cpp | 139 ++++++++++++++++++++++++ Source/Library/Userland/App/ShellApp.proto.h | 31 +++++- Source/Library/Userland/Start.cpp | 3 +- 15 files changed, 197 insertions(+), 30 deletions(-) create mode 100644 Source/Library/Userland/App/ShellApp.proto.cpp (limited to 'Source') diff --git a/Source/Applications/Demos/GOL.cpp b/Source/Applications/Demos/GOL.cpp index cd6e719..675c159 100644 --- a/Source/Applications/Demos/GOL.cpp +++ b/Source/Applications/Demos/GOL.cpp @@ -6,7 +6,7 @@ class GOL : public ShellApp { public: - GOL() : ShellApp() {} + GOL() : ShellApp("GOL.app", "Melon's Game of Life simulator \\o/") {} int run(); }; diff --git a/Source/Applications/Demos/cxxdemo.cpp b/Source/Applications/Demos/cxxdemo.cpp index 372e69f..36cfd27 100644 --- a/Source/Applications/Demos/cxxdemo.cpp +++ b/Source/Applications/Demos/cxxdemo.cpp @@ -6,7 +6,7 @@ class CPPDemo : public ShellApp { public: - CPPDemo() : ShellApp() {} + CPPDemo() : ShellApp("CPPDemo.app", "A demo application using the C++ Melon framework") {} int run(); }; diff --git a/Source/Applications/PaperWork/PaperWork.cpp b/Source/Applications/PaperWork/PaperWork.cpp index 0d6a821..4f9cb0e 100644 --- a/Source/Applications/PaperWork/PaperWork.cpp +++ b/Source/Applications/PaperWork/PaperWork.cpp @@ -4,7 +4,11 @@ class PaperWork : public ShellApp { public: - PaperWork() : ShellApp() {} + 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(); }; @@ -12,13 +16,7 @@ APP(PaperWork); int PaperWork::run() { String act = "init"; - if (args.size() == 2) { - if (args[1] == "login") { - act = "login"; - } else if (args[1] == "init") { - act = "init"; - } - } + if (bFlag("login")) act = "login"; if (act == "init") { while (1) { @@ -26,7 +24,7 @@ int PaperWork::run() { if (p.valid()) { p.setInVT(invt); p.setOutVT(outvt); - p.pushArg("login"); + p.pushArg("--login"); p.start(); p.wait(); } else { @@ -45,9 +43,9 @@ int PaperWork::run() { 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/Shell.class.cpp b/Source/Applications/Shell/Shell.class.cpp index 42743e7..4e0f18b 100644 --- a/Source/Applications/Shell/Shell.class.cpp +++ b/Source/Applications/Shell/Shell.class.cpp @@ -4,7 +4,7 @@ APP(Shell); -Shell::Shell() : ShellApp(), cwd(FS::cwdNode()) { +Shell::Shell() : ShellApp("Shell.app", "The Melon command line interpreter"), cwd(FS::cwdNode()) { } int Shell::run() { 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& args) { if (VFS::mount(args[1], m_vt)) *m_vt << "Ok, filesystem mounted.\n"; } } else { - *m_vt << "Usage: mount [ \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 { String(const char* string, u8int encoding = UE_UTF8); String() : BasicString() {} + String(WChar c, u32int n = 1) : BasicString(c, n) {} String(const String &other) : BasicString (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 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 index 1f3a963..46b0975 100644 --- a/Source/Library/Userland/App/Application.proto.h +++ b/Source/Library/Userland/App/Application.proto.h @@ -12,14 +12,13 @@ extern u32int start_dtors, end_dtors; class Application { public: Process pr; - Vector args; - Application() : pr(Process::get()), args(pr.argc()) { - for (u32int i = 0; i < args.size(); i++) args[i] = pr.argv(i); + 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() { 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 << " [-] \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 index 846f2b1..5575112 100644 --- a/Source/Library/Userland/App/ShellApp.proto.h +++ b/Source/Library/Userland/App/ShellApp.proto.h @@ -4,14 +4,35 @@ #include #include +#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; - - ShellApp() : Application(), invt(VirtualTerminal::getIn()), outvt(VirtualTerminal::getOut()) { - if (!invt.valid()) exit(1); - if (!outvt.valid()) exit(2); - } + Vector args; + Vector 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/Start.cpp b/Source/Library/Userland/Start.cpp index cb9faf9..3f825e9 100644 --- a/Source/Library/Userland/Start.cpp +++ b/Source/Library/Userland/Start.cpp @@ -9,8 +9,6 @@ extern u32int start_ctors, end_ctors; Heap *heap; -VirtualTerminal invt(0), outvt(0); - int main(const Vector& args); extern "C" void start() { @@ -24,6 +22,7 @@ extern "C" void start() { ((void (*)(void))*call)(); } + app->init(); app->doEvents(); u32int r = app->run(); app->doEvents(); -- cgit v1.2.3