[Add] CoW foundation and scriptable rm command.
Putting down the nessassary steps for the Copy-on-Write described in the previous commit. Implemented the first script based write command, 'rm'
This commit is contained in:
		
							parent
							
								
									ea0605711d
								
							
						
					
					
						commit
						b30c497769
					
				@ -1,5 +1,4 @@
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <SDL3/SDL.h>
 | 
			
		||||
#include <GL/glew.h>
 | 
			
		||||
#include <SDL3/SDL_events.h>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
#include "command_processor.h"
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include "vfs.h"
 | 
			
		||||
#include "lua_processor.h"
 | 
			
		||||
 | 
			
		||||
@ -22,7 +23,16 @@ std::string CommandProcessor::process_command(const std::string& command) {
 | 
			
		||||
  cmd = (end == std::string::npos) ? "" : cmd.substr(0, end+1);
 | 
			
		||||
 | 
			
		||||
  /* === Generic script executer. === */
 | 
			
		||||
  std::string command_name = cmd.substr(0, cmd.find(" "));
 | 
			
		||||
  /* Parse the command and it's arguments. */
 | 
			
		||||
  std::stringstream ss(cmd);
 | 
			
		||||
  std::string command_name;
 | 
			
		||||
  ss >> command_name;
 | 
			
		||||
 | 
			
		||||
  std::vector<std::string> args;
 | 
			
		||||
  std::string arg;
 | 
			
		||||
  while(ss >> arg) {
 | 
			
		||||
    args.push_back(arg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Search for script in the /bin directory. */
 | 
			
		||||
  std::string script_filename = command_name + ".lua";
 | 
			
		||||
@ -32,8 +42,7 @@ std::string CommandProcessor::process_command(const std::string& command) {
 | 
			
		||||
  }
 | 
			
		||||
  if(root->children.count("bin") && root->children["bin"]->children.count(script_filename)) {
 | 
			
		||||
    vfs_node* script_node = root->children["bin"]->children[script_filename];
 | 
			
		||||
    /* TODO: Pass arguments to the Lua script. */
 | 
			
		||||
    return _lua->execute(script_node->content, _current_dir);
 | 
			
		||||
    return _lua->execute(script_node->content, _current_dir, args);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,15 +8,45 @@ LuaProcessor::LuaProcessor(void) {
 | 
			
		||||
  _lua.new_usertype<vfs_node>("vfs_node",
 | 
			
		||||
                              "name",       &vfs_node::name,
 | 
			
		||||
                              "type",       &vfs_node::type,
 | 
			
		||||
                              "children",   &vfs_node::children);
 | 
			
		||||
                              "children",   &vfs_node::children,
 | 
			
		||||
                              "read_only",  &vfs_node::read_only);
 | 
			
		||||
 | 
			
		||||
  /* Create the 'vfs' table for our API. */
 | 
			
		||||
  sol::table vfs_api = _lua.create_table("vfs");
 | 
			
		||||
  vfs_api.set_function("rm", [](std::string path, vfs_node* current_dir) {
 | 
			
		||||
    /* for now, we'll just support deleting from the current directory. */
 | 
			
		||||
    if(current_dir->children.count(path)) {
 | 
			
		||||
      vfs_node* target_node = current_dir->children[path];
 | 
			
		||||
      if(target_node->read_only || current_dir->read_only) {
 | 
			
		||||
        return std::string("rm: Permission denied. File or directory is read-only.");
 | 
			
		||||
      }
 | 
			
		||||
      if(target_node->type == DIR_NODE) {
 | 
			
		||||
        return std::string("rm: cannot remove '" + path + "': Is a directory.");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      current_dir->children.erase(path);
 | 
			
		||||
      delete target_node; /* Clean up memry. */
 | 
			
		||||
      return std::string(""); /* Success. */
 | 
			
		||||
    }
 | 
			
		||||
    return std::string("rm: cannot remove '" + path + "': No such file or directory.");
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LuaProcessor::~LuaProcessor(void) {}
 | 
			
		||||
 | 
			
		||||
std::string LuaProcessor::execute(const std::string& script, vfs_node* current_dir) {
 | 
			
		||||
std::string LuaProcessor::execute(const std::string& script, vfs_node* current_dir,
 | 
			
		||||
                                  const std::vector<std::string>& args) {
 | 
			
		||||
  try {
 | 
			
		||||
    /* Pass the pointer for the current directory into the Lua env. */
 | 
			
		||||
    /* Pass C++ objects/points into the Lua env. */
 | 
			
		||||
    _lua["current_dir"] = current_dir;
 | 
			
		||||
 | 
			
		||||
    /* Create and populate the 'arg' table for the script. */
 | 
			
		||||
    sol::table arg_table = _lua.create_table();;;;
 | 
			
		||||
    for(size_t i = 0; i < args.size(); ++i) {
 | 
			
		||||
      arg_table[i+1] = args[i]; /* Lua array are 1-indexed. Not that Skuzzy would know. */
 | 
			
		||||
    }
 | 
			
		||||
    _lua["arg"] = arg_table;
 | 
			
		||||
 | 
			
		||||
    sol::object result = _lua.script(script);
 | 
			
		||||
    if(result.is<std::string>()) {
 | 
			
		||||
      return result.as<std::string>();
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,18 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <sol/sol.hpp>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <vfs.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
/* Don't want the full header. */
 | 
			
		||||
struct vfs_node;
 | 
			
		||||
 | 
			
		||||
class LuaProcessor {
 | 
			
		||||
public:
 | 
			
		||||
  LuaProcessor(void);
 | 
			
		||||
  ~LuaProcessor(void);
 | 
			
		||||
 | 
			
		||||
  /* Executes a string of lua code and returns result as a string. */
 | 
			
		||||
  std::string execute(const std::string& script, vfs_node* current_dir);
 | 
			
		||||
  std::string execute(const std::string& script, vfs_node* current_dir,
 | 
			
		||||
                      const std::vector<std::string>& args);
 | 
			
		||||
private:
 | 
			
		||||
  sol::state _lua;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ enum vfs_node_type {
 | 
			
		||||
struct vfs_node {
 | 
			
		||||
  std::string name;
 | 
			
		||||
  vfs_node_type type;
 | 
			
		||||
  bool read_only;
 | 
			
		||||
 | 
			
		||||
  /* Files. */
 | 
			
		||||
  std::string content;
 | 
			
		||||
 | 
			
		||||
@ -3,10 +3,11 @@
 | 
			
		||||
 | 
			
		||||
/* Create a new node. */
 | 
			
		||||
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent) {
 | 
			
		||||
  vfs_node* node = new vfs_node();
 | 
			
		||||
  node->name    = name;
 | 
			
		||||
  node->type    = type;
 | 
			
		||||
  node->parent  = parent;
 | 
			
		||||
  vfs_node* node  = new vfs_node();
 | 
			
		||||
  node->name      = name;
 | 
			
		||||
  node->type      = type;
 | 
			
		||||
  node->parent    = parent;
 | 
			
		||||
  node->read_only = false; /* Writable by default. */
 | 
			
		||||
  return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,6 +17,9 @@ VFSManager::VFSManager(void) {
 | 
			
		||||
  vfs_node* bin = new_node("bin", DIR_NODE, _vfs_root);
 | 
			
		||||
  _vfs_root->children["bin"] = bin;
 | 
			
		||||
 | 
			
		||||
  _vfs_root->read_only  = true;
 | 
			
		||||
  bin->read_only        = true;
 | 
			
		||||
 | 
			
		||||
  /* TODO:
 | 
			
		||||
   * Load all scripts from assets/scripts/bin into the bind node.
 | 
			
		||||
   * We'll create ls.lua manually for now.
 | 
			
		||||
@ -37,6 +41,14 @@ VFSManager::VFSManager(void) {
 | 
			
		||||
                             )lua";
 | 
			
		||||
 | 
			
		||||
  bin->children["ls.lua"] = ls_script;
 | 
			
		||||
 | 
			
		||||
  vfs_node* rm_script = new_node("rm.lua", FILE_NODE, bin);
 | 
			
		||||
  rm_script->content = R"lua(-- /bin/rm.lua - Removes a file.
 | 
			
		||||
                             local file_to_remove = arg[1]
 | 
			
		||||
                             if not file_to_remove then return "rm: missing operand" end
 | 
			
		||||
                             return vfs.rm(file_to_remove, current_dir)
 | 
			
		||||
                             )lua";
 | 
			
		||||
  bin->children["rm.lua"] = rm_script;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VFSManager::~VFSManager(void) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user