sub-invoke()
This commit is contained in:
Binary file not shown.
+2
-3
@@ -16,14 +16,13 @@ mkdir bin/assets > /dev/null 2>&1
|
|||||||
mkdir work > /dev/null 2>&1
|
mkdir work > /dev/null 2>&1
|
||||||
|
|
||||||
COMPILER="clang++"
|
COMPILER="clang++"
|
||||||
FLAGS="-w -Wall -$OPT_FLAG -std=c++17 -fpermissive -ffast-math"
|
FLAGS="-g -w -Wall -$OPT_FLAG -std=c++17 -fpermissive -ffast-math"
|
||||||
|
|
||||||
LIBS="-ldl -lm -lpthread "
|
LIBS="-ldl -lm -lpthread "
|
||||||
SRCFLAGS="-D EXEC_NAME=\"$GF\" -D PLATFORM_NAME=\"linux\""
|
SRCFLAGS="-D EXEC_NAME=\"$GF\" -D PLATFORM_NAME=\"linux\""
|
||||||
|
|
||||||
echo "Compliling executable..."
|
echo "Compliling executable..."
|
||||||
#time -p
|
time -p $COMPILER src/linux_fastcgi.cpp $SRCFLAGS $FLAGS $LIBS -o bin/$GF.$BUILDMODE.linux.bin 2>&1
|
||||||
$COMPILER src/linux_fastcgi.cpp $SRCFLAGS $FLAGS $LIBS -o bin/$GF.$BUILDMODE.linux.bin 2>&1
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]
|
if [ $? -eq 0 ]
|
||||||
then
|
then
|
||||||
|
|||||||
+89
-67
@@ -1,31 +1,6 @@
|
|||||||
#include <dlfcn.h>
|
|
||||||
|
|
||||||
#define RENDER() extern "C" void render()
|
#define RENDER() extern "C" void render()
|
||||||
|
|
||||||
typedef void (*call_handler)();
|
string process_html_literal(SharedUnit* su, string content)
|
||||||
typedef void (*request_handler)(Request* request);
|
|
||||||
|
|
||||||
struct SharedUnit {
|
|
||||||
string file_name;
|
|
||||||
string so_name;
|
|
||||||
void* so_handle;
|
|
||||||
request_handler on_setup;
|
|
||||||
call_handler on_render;
|
|
||||||
string compiler_messages;
|
|
||||||
time_t last_compiled;
|
|
||||||
|
|
||||||
~SharedUnit()
|
|
||||||
{
|
|
||||||
if(so_handle)
|
|
||||||
{
|
|
||||||
dlclose(so_handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<string, SharedUnit*> units;
|
|
||||||
|
|
||||||
string process_html_literal(string content, string file_name)
|
|
||||||
{
|
{
|
||||||
string pc;
|
string pc;
|
||||||
string HT_START = "context->print(R\"(";
|
string HT_START = "context->print(R\"(";
|
||||||
@@ -99,9 +74,10 @@ string process_html_literal(string content, string file_name)
|
|||||||
return(HT_START + pc + HT_END);
|
return(HT_START + pc + HT_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
string preprocess(string content, string file_name)
|
string preprocess_shared_unit(SharedUnit* su)
|
||||||
{
|
{
|
||||||
string pc = "#include \""+get_cwd()+"/src/lib/uce_gen.h\" \n";
|
string content = file_get_contents(su->file_name);
|
||||||
|
string pc = "#include \""+context->server_state->config.COMPILER_SYS_PATH +"/src/lib/uce_gen.h\" \n";
|
||||||
string token = "";
|
string token = "";
|
||||||
string html_buffer = "";
|
string html_buffer = "";
|
||||||
u8 mode = 0;
|
u8 mode = 0;
|
||||||
@@ -117,11 +93,11 @@ string preprocess(string content, string file_name)
|
|||||||
u32 len = token.length() + 3 + end_pos - i;
|
u32 len = token.length() + 3 + end_pos - i;
|
||||||
html_buffer.append(content.substr(i, len - (token.length() == 0 ? 3 : 0)));
|
html_buffer.append(content.substr(i, len - (token.length() == 0 ? 3 : 0)));
|
||||||
i += len - 1;
|
i += len - 1;
|
||||||
pc.append(process_html_literal(html_buffer, file_name));
|
pc.append(process_html_literal(su, html_buffer));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("(!) unterminated HTML literal <%s> in %s", token.c_str(), file_name.c_str());
|
printf("(!) unterminated HTML literal <%s> in %s", token.c_str(), su->file_name.c_str());
|
||||||
}
|
}
|
||||||
mode = 0;
|
mode = 0;
|
||||||
}
|
}
|
||||||
@@ -160,9 +136,39 @@ string preprocess(string content, string file_name)
|
|||||||
return(pc);
|
return(pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_shared_unit(SharedUnit* su)
|
void setup_unit_paths(SharedUnit* su, string file_name)
|
||||||
{
|
{
|
||||||
|
su->file_name = file_name;
|
||||||
|
|
||||||
|
if(su->src_path.length() > 0) // we did this already
|
||||||
|
return;
|
||||||
|
|
||||||
|
su->src_path = dirname(file_name);
|
||||||
|
su->bin_path = context->server_state->config.BIN_DIRECTORY + su->src_path;
|
||||||
|
su->pre_path = context->server_state->config.BIN_DIRECTORY + su->src_path;
|
||||||
|
|
||||||
|
su->src_file_name = basename(file_name);
|
||||||
|
su->bin_file_name = su->src_file_name + ".so";
|
||||||
|
su->pre_file_name = su->src_file_name + ".cpp";
|
||||||
|
|
||||||
|
su->so_name = su->bin_path + "/" + su->bin_file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_shared_unit(SharedUnit* su, string file_name)
|
||||||
|
{
|
||||||
|
setup_unit_paths(su, file_name);
|
||||||
|
|
||||||
su->on_render = 0;
|
su->on_render = 0;
|
||||||
|
su->on_setup = 0;
|
||||||
|
su->compiler_messages = "";
|
||||||
|
|
||||||
|
if(!file_exists(su->so_name))
|
||||||
|
{
|
||||||
|
printf("(i) unit file not found: %s\n", su->so_name.c_str());
|
||||||
|
su->compiler_messages = "unit file not found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
su->so_handle = dlopen(su->so_name.c_str(), RTLD_NOW);
|
su->so_handle = dlopen(su->so_name.c_str(), RTLD_NOW);
|
||||||
if(su->so_handle)
|
if(su->so_handle)
|
||||||
{
|
{
|
||||||
@@ -181,79 +187,95 @@ void load_shared_unit(SharedUnit* su)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedUnit* compile_shared_unit(string file_name)
|
void compile_shared_unit(SharedUnit* su, string file_name)
|
||||||
{
|
{
|
||||||
SharedUnit* su = new SharedUnit();
|
setup_unit_paths(su, file_name);
|
||||||
|
|
||||||
string src_path = dirname(file_name);
|
if(!file_exists(su->file_name))
|
||||||
string src_fn = basename(file_name);
|
{
|
||||||
string dest_path = Config.BIN_DIRECTORY + src_path;
|
su->compiler_messages = "source file not found";
|
||||||
string pp_fn = src_fn + ".cpp";
|
return;
|
||||||
string so_fn = src_fn + ".so";
|
}
|
||||||
|
|
||||||
su->file_name = file_name;
|
shell_exec("mkdir -p " + shell_escape(su->pre_path));
|
||||||
su->so_name = dest_path + "/" + so_fn;
|
file_put_contents(su->pre_path + "/" + su->pre_file_name, preprocess_shared_unit(su));
|
||||||
|
|
||||||
string pc = preprocess(file_get_contents(file_name), file_name);
|
printf("Config.COMPILE_SCRIPT %s\n", string(su->pre_path + "/" + su->pre_file_name).c_str());
|
||||||
file_put_contents(dest_path + "/" + pp_fn, pc);
|
|
||||||
|
|
||||||
su->compiler_messages = trim(shell_exec(Config.COMPILE_SCRIPT+" "+
|
su->compiler_messages = trim(shell_exec(context->server_state->config.COMPILE_SCRIPT+" "+
|
||||||
shell_escape(src_path)+" "+
|
shell_escape(su->src_path)+" "+
|
||||||
shell_escape(dest_path)+" "+
|
shell_escape(su->bin_path)+" "+
|
||||||
shell_escape(src_fn)+" "+
|
shell_escape(su->file_name)+" "+
|
||||||
shell_escape(pp_fn)+" "+
|
shell_escape(su->pre_file_name)+" "+
|
||||||
shell_escape(so_fn)
|
shell_escape(su->bin_file_name)
|
||||||
));
|
));
|
||||||
|
|
||||||
if(su->compiler_messages.length() > 0)
|
if(su->compiler_messages.length() > 0)
|
||||||
|
{
|
||||||
printf("%s \n", su->compiler_messages.c_str());
|
printf("%s \n", su->compiler_messages.c_str());
|
||||||
|
}
|
||||||
printf("(i) compiled unit %s\n", file_name.c_str());
|
else
|
||||||
|
{
|
||||||
load_shared_unit(su);
|
load_shared_unit(su, file_name);
|
||||||
|
printf("(i) compiled unit %s\n", file_name.c_str());
|
||||||
return(su);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedUnit* get_shared_unit(string file_name)
|
SharedUnit* get_shared_unit(string file_name)
|
||||||
{
|
{
|
||||||
SharedUnit* su = units[file_name];
|
SharedUnit* su = context->server_state->units[file_name];
|
||||||
if(su && su->last_compiled < file_mtime(file_name))
|
auto mod_time = file_mtime(file_name);
|
||||||
|
bool do_recompile = false;
|
||||||
|
if(su && (su->last_compiled < mod_time || mod_time == 0))
|
||||||
{
|
{
|
||||||
delete su;
|
delete su;
|
||||||
su = 0;
|
su = 0;
|
||||||
|
do_recompile = true;
|
||||||
}
|
}
|
||||||
if(!su)
|
if(!su)
|
||||||
{
|
{
|
||||||
su = units[file_name] = compile_shared_unit(file_name);
|
su = new SharedUnit();
|
||||||
|
|
||||||
|
if(do_recompile)
|
||||||
|
{
|
||||||
|
compile_shared_unit(su, file_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
load_shared_unit(su, file_name);
|
||||||
|
if(!su->so_handle)
|
||||||
|
compile_shared_unit(su, file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
context->server_state->units[file_name] = su;
|
||||||
}
|
}
|
||||||
return(su);
|
return(su);
|
||||||
}
|
}
|
||||||
|
|
||||||
void invoke(Request* req, string file_name)
|
void invoke(string file_name)
|
||||||
{
|
{
|
||||||
|
printf("(i) invoke(%s)\n", file_name.c_str());
|
||||||
auto su = get_shared_unit(file_name);
|
auto su = get_shared_unit(file_name);
|
||||||
if(!su)
|
if(!su)
|
||||||
{
|
{
|
||||||
printf("Error loading unit %s\n", su->file_name.c_str());
|
printf("Error loading unit %s\n", file_name.c_str());
|
||||||
|
context->print("Error loading unit: "+file_name);
|
||||||
}
|
}
|
||||||
else if(!su->on_render)
|
else if(!su->on_render)
|
||||||
{
|
{
|
||||||
req->print("Compiler error: "+su->compiler_messages);
|
context->print("Compiler error: "+su->compiler_messages);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(su->compiler_messages.length() > 0)
|
if(su->compiler_messages.length() > 0)
|
||||||
req->print(su->compiler_messages);
|
context->print(su->compiler_messages);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
su->on_setup(req);
|
string prev_wd = get_cwd();
|
||||||
|
set_cwd(su->src_path);
|
||||||
|
su->on_setup(context);
|
||||||
su->on_render();
|
su->on_render();
|
||||||
|
set_cwd(prev_wd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void invoke(string file_name)
|
|
||||||
{
|
|
||||||
return(invoke(context, file_name));
|
|
||||||
}
|
|
||||||
|
|||||||
+3
-2
@@ -1,4 +1,4 @@
|
|||||||
struct Settings {
|
struct ServerSettings {
|
||||||
|
|
||||||
string BIN_DIRECTORY = "work";
|
string BIN_DIRECTORY = "work";
|
||||||
string COMPILE_SCRIPT = "scripts/compile";
|
string COMPILE_SCRIPT = "scripts/compile";
|
||||||
@@ -6,6 +6,7 @@ struct Settings {
|
|||||||
string CONTENT_TYPE = "text/html; charset=utf-8";
|
string CONTENT_TYPE = "text/html; charset=utf-8";
|
||||||
string SOCKET_PATH = "/run/uce.sock";
|
string SOCKET_PATH = "/run/uce.sock";
|
||||||
string TMP_UPLOAD = "/tmp";
|
string TMP_UPLOAD = "/tmp";
|
||||||
|
string COMPILER_SYS_PATH = "";
|
||||||
u32 LISTEN_PORT = 9993;
|
u32 LISTEN_PORT = 9993;
|
||||||
|
|
||||||
} Config;
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
string shell_exec(string cmd)
|
string shell_exec(string cmd)
|
||||||
{
|
{
|
||||||
|
printf("(i) shell_exec(%s)\n", cmd.c_str());
|
||||||
string data;
|
string data;
|
||||||
FILE * stream;
|
FILE * stream;
|
||||||
const int max_buffer = 256;
|
const int max_buffer = 256;
|
||||||
@@ -98,6 +99,11 @@ string get_cwd()
|
|||||||
return(std::filesystem::current_path());
|
return(std::filesystem::current_path());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_cwd(string path)
|
||||||
|
{
|
||||||
|
chdir(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
time_t file_mtime(string file_name)
|
time_t file_mtime(string file_name)
|
||||||
{
|
{
|
||||||
struct stat info;
|
struct stat info;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
typedef std::string string;
|
typedef std::string string;
|
||||||
|
|
||||||
@@ -33,11 +34,47 @@ typedef long long s64;
|
|||||||
typedef std::map<string, string> StringMap;
|
typedef std::map<string, string> StringMap;
|
||||||
typedef std::vector<string> StringList;
|
typedef std::vector<string> StringList;
|
||||||
|
|
||||||
|
typedef void (*invoke_handler)(string file_name);
|
||||||
|
|
||||||
struct UploadedFile {
|
struct UploadedFile {
|
||||||
string file_name;
|
string file_name;
|
||||||
string tmp_name;
|
string tmp_name;
|
||||||
u32 size;
|
u32 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Request;
|
||||||
|
|
||||||
|
typedef void (*call_handler)();
|
||||||
|
typedef void (*request_handler)(Request* request);
|
||||||
|
|
||||||
|
struct SharedUnit {
|
||||||
|
|
||||||
|
string file_name;
|
||||||
|
string so_name;
|
||||||
|
|
||||||
|
string src_path;
|
||||||
|
string bin_path;
|
||||||
|
string pre_path;
|
||||||
|
string src_file_name;
|
||||||
|
string bin_file_name;
|
||||||
|
string pre_file_name;
|
||||||
|
|
||||||
|
void* so_handle;
|
||||||
|
|
||||||
|
request_handler on_setup;
|
||||||
|
call_handler on_render;
|
||||||
|
|
||||||
|
string compiler_messages;
|
||||||
|
time_t last_compiled;
|
||||||
|
|
||||||
|
~SharedUnit()
|
||||||
|
{
|
||||||
|
if(so_handle)
|
||||||
|
{
|
||||||
|
dlclose(so_handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#include "dtree.h"
|
#include "dtree.h"
|
||||||
|
|
||||||
|
|||||||
+14
-4
@@ -3,9 +3,17 @@
|
|||||||
#include "datastructures.h"
|
#include "datastructures.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "uri.h"
|
|
||||||
|
|
||||||
struct FastCGIRequest {
|
struct ServerState {
|
||||||
|
|
||||||
|
std::map<string, SharedUnit*> units;
|
||||||
|
ServerSettings config;
|
||||||
|
|
||||||
|
} server_state;
|
||||||
|
|
||||||
|
struct Request {
|
||||||
|
|
||||||
|
ServerState* server_state;
|
||||||
|
|
||||||
StringMap params;
|
StringMap params;
|
||||||
StringMap get;
|
StringMap get;
|
||||||
@@ -29,13 +37,15 @@ struct FastCGIRequest {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef FastCGIRequest Request;
|
typedef Request FastCGIRequest;
|
||||||
|
|
||||||
Request* context;
|
Request* context;
|
||||||
|
|
||||||
|
#include "uri.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
extern "C" void set_current_request(Request* _request)
|
extern "C" void set_current_request(Request* _request)
|
||||||
{
|
{
|
||||||
context = _request;
|
context = _request;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "compiler.h"
|
|
||||||
|
|||||||
+1
-1
@@ -177,7 +177,7 @@ struct URI {
|
|||||||
{
|
{
|
||||||
nibble("=\"", field);
|
nibble("=\"", field);
|
||||||
UploadedFile f;
|
UploadedFile f;
|
||||||
f.tmp_name = Config.TMP_UPLOAD + to_string(rand());
|
f.tmp_name = context->server_state->config.TMP_UPLOAD + to_string(rand());
|
||||||
f.file_name = nibble("\"", field);
|
f.file_name = nibble("\"", field);
|
||||||
string bin = field.substr(4, field.length()-6);
|
string bin = field.substr(4, field.length()-6);
|
||||||
f.size = bin.length();
|
f.size = bin.length();
|
||||||
|
|||||||
+15
-7
@@ -38,9 +38,11 @@ int handle_complete(FastCGIRequest& request) {
|
|||||||
// The event handler can also be a class member function. This
|
// The event handler can also be a class member function. This
|
||||||
// event occurs when the parameters and standard input streams are
|
// event occurs when the parameters and standard input streams are
|
||||||
// both closed, and thus the request is complete.
|
// both closed, and thus the request is complete.
|
||||||
|
context = &request;
|
||||||
|
request.server_state = &server_state;
|
||||||
request.time_start = microtime();
|
request.time_start = microtime();
|
||||||
|
|
||||||
request.header["Content-Type"] = Config.CONTENT_TYPE;
|
request.header["Content-Type"] = context->server_state->config.CONTENT_TYPE;
|
||||||
request.get = URI::parse_query(request.params["QUERY_STRING"]);
|
request.get = URI::parse_query(request.params["QUERY_STRING"]);
|
||||||
|
|
||||||
string ct_info = request.params["CONTENT_TYPE"];
|
string ct_info = request.params["CONTENT_TYPE"];
|
||||||
@@ -59,7 +61,7 @@ int handle_complete(FastCGIRequest& request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
invoke(&request, request.params["SCRIPT_FILENAME"]);
|
invoke(request.params["SCRIPT_FILENAME"]);
|
||||||
|
|
||||||
string headers = var_dump(request.header, "", "\r\n") + "\r\n";
|
string headers = var_dump(request.header, "", "\r\n") + "\r\n";
|
||||||
request.out = headers + request.out;
|
request.out = headers + request.out;
|
||||||
@@ -87,11 +89,17 @@ int main(int argc, char** argv)
|
|||||||
server.data_handler(&handle_data);
|
server.data_handler(&handle_data);
|
||||||
server.complete_handler(&handle_complete);
|
server.complete_handler(&handle_complete);
|
||||||
|
|
||||||
if(Config.LISTEN_PORT)
|
if(server_state.config.COMPILER_SYS_PATH == "")
|
||||||
server.listen(Config.LISTEN_PORT);
|
server_state.config.COMPILER_SYS_PATH = get_cwd();
|
||||||
if(Config.SOCKET_PATH != "")
|
server_state.config.BIN_DIRECTORY =
|
||||||
server.listen(Config.SOCKET_PATH);
|
server_state.config.COMPILER_SYS_PATH + "/" + server_state.config.BIN_DIRECTORY;
|
||||||
chmod(Config.SOCKET_PATH.c_str(), S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
server_state.config.COMPILE_SCRIPT =
|
||||||
|
server_state.config.COMPILER_SYS_PATH + "/" + server_state.config.COMPILE_SCRIPT;
|
||||||
|
if(server_state.config.LISTEN_PORT)
|
||||||
|
server.listen(server_state.config.LISTEN_PORT);
|
||||||
|
if(server_state.config.SOCKET_PATH != "")
|
||||||
|
server.listen(server_state.config.SOCKET_PATH);
|
||||||
|
chmod(server_state.config.SOCKET_PATH.c_str(), S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||||
|
|
||||||
//server.process(100);
|
//server.process(100);
|
||||||
//server.process();
|
//server.process();
|
||||||
|
|||||||
+2
-1
@@ -4,7 +4,7 @@ RENDER()
|
|||||||
{
|
{
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<link rel="stylesheet" href='style.css?v=1'></link>
|
<link rel="stylesheet" href='style.css'></link>
|
||||||
<h1>
|
<h1>
|
||||||
<a href="index.uce">UCE Test</a>:
|
<a href="index.uce">UCE Test</a>:
|
||||||
Index
|
Index
|
||||||
@@ -13,6 +13,7 @@ RENDER()
|
|||||||
<li><a href="hello.uce">Hello</a></li>
|
<li><a href="hello.uce">Hello</a></li>
|
||||||
<li><a href="post.uce">Form Post</a></li>
|
<li><a href="post.uce">Form Post</a></li>
|
||||||
<li><a href="post-multipart.uce">Form Multipart Post</a></li>
|
<li><a href="post-multipart.uce">Form Multipart Post</a></li>
|
||||||
|
<li><a href="working-dir.uce">Working Directory</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<pre><?= var_dump(context->params) ?></pre>
|
<pre><?= var_dump(context->params) ?></pre>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+2
-1
@@ -65,7 +65,8 @@ textarea {
|
|||||||
pre {
|
pre {
|
||||||
height: 20%;
|
height: 20%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding. 8px;
|
padding: 8px;
|
||||||
border: 2px solid rgba(0,0,0,0.2);
|
border: 2px solid rgba(0,0,0,0.2);
|
||||||
background: rgba(100,100,100,0.15);
|
background: rgba(100,100,100,0.15);
|
||||||
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
RENDER()
|
||||||
|
{
|
||||||
|
echo("Sub-Invoke Working dir: " + get_cwd() + "\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
RENDER()
|
||||||
|
{
|
||||||
|
|
||||||
|
<>
|
||||||
|
<link rel="stylesheet" href='style.css'></link>
|
||||||
|
<h1>
|
||||||
|
<a href="index.uce">UCE Test</a>:
|
||||||
|
Working Directory
|
||||||
|
</h1>
|
||||||
|
<pre><?
|
||||||
|
echo("Base WD: " + get_cwd() + "\n");
|
||||||
|
invoke("/Code/uce.openfu.com/uce/test/test2/working-dir-test.uce");
|
||||||
|
?></pre>
|
||||||
|
<pre><?= var_dump(context->params) ?></pre>
|
||||||
|
</>
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user