playing with a packaging VM
This commit is contained in:
parent
3ad502780f
commit
767cc164d5
|
@ -1,50 +1,875 @@
|
||||||
/*
|
/*
|
||||||
4tech_file_moving.h - Code for moving files around on the file system.
|
* Mr. 4th Dimention - Allen Webster
|
||||||
By Allen Webster
|
*
|
||||||
21.01.2017 (dd.mm.yyyy)
|
* 21.01.2017
|
||||||
*/
|
*
|
||||||
|
* Code for file manipulating scripts.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
#if !defined(FTECH_FILE_MOVING_H)
|
#if !defined(FTECH_FILE_MOVING_H)
|
||||||
#define FTECH_FILE_MOVING_H
|
#define FTECH_FILE_MOVING_H
|
||||||
|
|
||||||
|
#include "../4tech_defines.h"
|
||||||
|
#include "../4coder_lib/4coder_string.h"
|
||||||
|
|
||||||
#include <stdio.h> // include system for windows
|
#include <stdio.h> // include system for windows
|
||||||
#include <stdlib.h> // include system for linux (YAY!)
|
#include <stdlib.h> // include system for linux (YAY!)
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// NOTE(allen): Compiler/OS cracking.
|
static char SF_CMD[4096];
|
||||||
#if defined(_MSC_VER)
|
static i32 error_state = 0;
|
||||||
|
static i32 prev_error = 0;
|
||||||
|
|
||||||
# if !defined(IS_CL)
|
#define systemf(...) do{ \
|
||||||
# define IS_CL
|
int32_t n = snprintf(SF_CMD, sizeof(SF_CMD), __VA_ARGS__); \
|
||||||
# endif
|
AllowLocal(n); \
|
||||||
|
Assert(n < sizeof(SF_CMD)); \
|
||||||
# define snprintf _snprintf
|
/** printf("%s\n", SF_CMD); /**/ \
|
||||||
|
prev_error = system(SF_CMD); \
|
||||||
# if defined(_WIN32)
|
if (prev_error != 0) error_state = 1; \
|
||||||
# define IS_WINDOWS
|
}while(0)
|
||||||
# pragma comment(lib, "Kernel32.lib")
|
|
||||||
# else
|
|
||||||
# error This compiler/platform combo is not supported yet
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
|
||||||
|
|
||||||
# if !defined(IS_GCC)
|
|
||||||
# define IS_GCC
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if defined(__gnu_linux__)
|
|
||||||
# define IS_LINUX
|
|
||||||
# else
|
|
||||||
# error This compiler/platform combo is not supported yet
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
// OS selectors
|
||||||
|
#if defined(IS_WINDOWS)
|
||||||
|
# define ONLY_WINDOWS(x) x
|
||||||
|
# define ONLY_LINUX(x) (void)0
|
||||||
|
#elif defined(IS_LINUX)
|
||||||
|
# define ONLY_WINDOWS(x) (void)0
|
||||||
|
# define ONLY_LINUX(x) x
|
||||||
#else
|
#else
|
||||||
#error This compiler is not supported yet
|
# error File moving is not setup on this OS.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// String helpers
|
||||||
|
internal void
|
||||||
|
require_size(String *str, i32 size){
|
||||||
|
if (str->memory_size <= size){
|
||||||
|
free(str->str);
|
||||||
|
str->memory_size = l_round_up_i32(str->size*2, 64);
|
||||||
|
str->str = (char*)malloc(str->memory_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal void
|
||||||
|
require_size_preserve(String *str, i32 size){
|
||||||
|
if (str->memory_size <= size){
|
||||||
|
str->memory_size = l_round_up_i32(str->size*2, 64);
|
||||||
|
char *newstr = (char*)malloc(str->memory_size);
|
||||||
|
memcpy(newstr, str->str, str->size);
|
||||||
|
free(str->str);
|
||||||
|
str->str = newstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
copy_always(String *dst, String src){
|
||||||
|
require_size(dst, src.size+1);
|
||||||
|
copy(dst, src);
|
||||||
|
terminate_with_null(dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
append_always(String *dst, String src){
|
||||||
|
require_size_preserve(dst, dst->size+src.size+1);
|
||||||
|
append(dst, src);
|
||||||
|
terminate_with_null(dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instruction format
|
||||||
|
typedef u16 Instruction_FM;
|
||||||
|
enum Instruction_FM_{
|
||||||
|
InstrFM_BeginTime,
|
||||||
|
InstrFM_EndTime,
|
||||||
|
InstrFM_Push,
|
||||||
|
InstrFM_StackLoad,
|
||||||
|
InstrFM_Pop,
|
||||||
|
InstrFM_MovCWD,
|
||||||
|
InstrFM_Mov,
|
||||||
|
InstrFM_Leaf,
|
||||||
|
InstrFM_Path,
|
||||||
|
InstrFM_Cat,
|
||||||
|
InstrFM_SlashFix,
|
||||||
|
InstrFM_MkDir,
|
||||||
|
InstrFM_ClrDir,
|
||||||
|
InstrFM_Del,
|
||||||
|
InstrFM_Copy,
|
||||||
|
InstrFM_CopyAll,
|
||||||
|
InstrFM_Zip,
|
||||||
|
InstrFM_CD,
|
||||||
|
InstrFM_Command,
|
||||||
|
InstrFM_COUNT
|
||||||
|
};
|
||||||
|
enum Instruction_Flag_FM_{
|
||||||
|
InstrFM_LiteralParam1 = 0x8000,
|
||||||
|
InstrFM_LiteralParam2 = 0x4000,
|
||||||
|
InstrFM_LiteralParam3 = 0x2000,
|
||||||
|
InstrFM_InstrMask = 0x00FF
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef u16 String_Reg;
|
||||||
|
|
||||||
|
// Instruction VM
|
||||||
|
#define REG_COUNT_FM 16
|
||||||
|
struct Virtual_Machine_FM{
|
||||||
|
umem pc;
|
||||||
|
u64 time_start;
|
||||||
|
String temp;
|
||||||
|
String stage_reg;
|
||||||
|
String reg[REG_COUNT_FM];
|
||||||
|
|
||||||
|
String *stack_base;
|
||||||
|
String *stack_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal String_Reg
|
||||||
|
read_register_fm(u8 **ptr){
|
||||||
|
String_Reg result = *(String_Reg*)(*ptr);
|
||||||
|
Assert(result < REG_COUNT_FM);
|
||||||
|
(*ptr) += 2;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal u16
|
||||||
|
read_u16_fm(u8 **ptr){
|
||||||
|
u16 result = *(u16*)(*ptr);
|
||||||
|
(*ptr) += 2;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String
|
||||||
|
read_parameter_fm(b32 is_literal, u8 **ptr){
|
||||||
|
String result = {0};
|
||||||
|
if (is_literal){
|
||||||
|
result.size = *(u16*)(*ptr);
|
||||||
|
result.memory_size = result.size+1;
|
||||||
|
(*ptr) += 2;
|
||||||
|
result.str = (char*)ptr;
|
||||||
|
u16 step_forward = (result.memory_size+1)&(~1);
|
||||||
|
ptr += step_forward;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
String_Reg result = *(String_Reg*)(*ptr);
|
||||||
|
Assert(result < REG_COUNT_FM);
|
||||||
|
(*ptr) += 2;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
stage_params(String *params, u32 count, u16 dest, Virtual_Machine_FM *vm){
|
||||||
|
String dest_str = vm->reg[dest];
|
||||||
|
u32 i = 0;
|
||||||
|
for (; i < count; ++i){
|
||||||
|
if (params[i].str == dest_str.str){
|
||||||
|
copy_always(&vm->stage_reg, params[i]);
|
||||||
|
params[i] = vm->stage_reg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (++i; i < count; ++i){
|
||||||
|
if (params[i].str == dest_str.str){
|
||||||
|
params[i] = vm->stage_reg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void run_instruction_fm(Virtual_Machine_FM *vm, u16 op, String_Reg dest, u16 n, String *params);
|
||||||
|
|
||||||
|
internal void
|
||||||
|
execute_instructions_fm(void *code, umem length){
|
||||||
|
Assert(InstrFM_InstrMask >= InstrFM_COUNT-1);
|
||||||
|
|
||||||
|
u8 *base = (u8*)code;
|
||||||
|
Virtual_Machine_FM vm = {0};
|
||||||
|
|
||||||
|
u32 n = 0;
|
||||||
|
String_Reg dest = 0;
|
||||||
|
String param[3] = {0};
|
||||||
|
for (;vm.pc < length;){
|
||||||
|
Instruction_FM ins = *(Instruction_FM*)(base+vm.pc);
|
||||||
|
u16 op = (ins)&InstrFM_InstrMask;
|
||||||
|
|
||||||
|
u8 *ptr = (u8*)(base+vm.pc+2);
|
||||||
|
switch(op){
|
||||||
|
case InstrFM_MovCWD:
|
||||||
|
{
|
||||||
|
dest = read_register_fm(&ptr);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_StackLoad:
|
||||||
|
{
|
||||||
|
dest = read_register_fm(&ptr);
|
||||||
|
n = read_u16_fm(&ptr);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Pop:
|
||||||
|
{
|
||||||
|
n = read_u16_fm(&ptr);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Mov:
|
||||||
|
case InstrFM_Leaf:
|
||||||
|
case InstrFM_Path:
|
||||||
|
case InstrFM_Cat:
|
||||||
|
case InstrFM_SlashFix:
|
||||||
|
{
|
||||||
|
dest = read_register_fm(&ptr);
|
||||||
|
param[0] = read_parameter_fm(ins&InstrFM_LiteralParam1, &ptr);
|
||||||
|
stage_params(param, 1, dest, &vm);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Push:
|
||||||
|
case InstrFM_EndTime:
|
||||||
|
case InstrFM_MkDir:
|
||||||
|
case InstrFM_ClrDir:
|
||||||
|
case InstrFM_Del:
|
||||||
|
case InstrFM_CD:
|
||||||
|
case InstrFM_Command:
|
||||||
|
{
|
||||||
|
param[0] = read_parameter_fm(ins&InstrFM_LiteralParam1, &ptr);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Copy:
|
||||||
|
case InstrFM_Zip:
|
||||||
|
{
|
||||||
|
param[0] = read_parameter_fm(ins&InstrFM_LiteralParam1, &ptr);
|
||||||
|
param[1] = read_parameter_fm(ins&InstrFM_LiteralParam2, &ptr);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_CopyAll:
|
||||||
|
{
|
||||||
|
param[0] = read_parameter_fm(ins&InstrFM_LiteralParam1, &ptr);
|
||||||
|
param[1] = read_parameter_fm(ins&InstrFM_LiteralParam2, &ptr);
|
||||||
|
param[2] = read_parameter_fm(ins&InstrFM_LiteralParam3, &ptr);
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
run_instruction_fm(&vm, op, dest, n, param);
|
||||||
|
|
||||||
|
vm.pc = (umem)((ptr)-(base+vm.pc));
|
||||||
|
Assert(vm.pc <= length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LLU_CAST(n) (long long unsigned int)(n)
|
||||||
|
#define TSCALE 1000000
|
||||||
|
#define PRINT_TIME_FM(n) \
|
||||||
|
printf("%-20s: %.2llu.%.6llu\n", (n), LLU_CAST(total/TSCALE), LLU_CAST(total%TSCALE));
|
||||||
|
|
||||||
|
#if defined(IS_WINDOWS)
|
||||||
|
|
||||||
|
#define DONT_BUG_ME\
|
||||||
|
FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR
|
||||||
|
|
||||||
|
internal void
|
||||||
|
run_instruction_fm(Virtual_Machine_FM *vm, u16 op, String_Reg dest, String *params){
|
||||||
|
switch(op){
|
||||||
|
case InstrFM_BeginTime:
|
||||||
|
case InstrFM_EndTime:
|
||||||
|
{
|
||||||
|
u64 time = 0;
|
||||||
|
LARGE_INTEGER lint;
|
||||||
|
if (QueryPerformanceCounter(&lint)){
|
||||||
|
time = lint.QuadPart;
|
||||||
|
time = (time * 1000000) / perf_frequency;
|
||||||
|
}
|
||||||
|
if (op == InstrFM_BeginTime){
|
||||||
|
vm->time_start = time;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
u64 total = time - vm->time_start;
|
||||||
|
PRINT_TIME_FM(params[0].str);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_MovCWD:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
i32 length = GetCurrentDirectoryA(0, 0);
|
||||||
|
require_size(d, length+1);
|
||||||
|
d->size = GetCurrentDirectoryA(d->memory_size, d->str);
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Push:
|
||||||
|
{
|
||||||
|
copy_always(&vm->stack_ptr[0], params[0]);
|
||||||
|
++vm->stack_ptr;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_StackLoad:
|
||||||
|
{
|
||||||
|
Assert((vm->stack_ptr - vm->stack_base) >= n);
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
String *s = vm->stack_ptr - n;
|
||||||
|
copy_always(d, *s);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Pop:
|
||||||
|
{
|
||||||
|
Assert((vm->stack_ptr - vm->stack_base) >= n);
|
||||||
|
stack_ptr = vm->strack_ptr - n;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Mov:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
copy_always(d, params[0]);
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Leaf:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
copy_always(d, front_of_directory(params[0]));
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Path:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
copy_always(d, path_of_directory(params[0]));
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Cat:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
append_always(d, params[0]);
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_SlashFix:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
copy_always(d, params[0]);
|
||||||
|
u32 size = d->size;
|
||||||
|
char *str = d->str;
|
||||||
|
for (u32 i = 0; i < size; ++i){
|
||||||
|
if (str[i] == '/'){
|
||||||
|
str[i] == '//';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_MkDir:
|
||||||
|
{
|
||||||
|
String path = param[0];
|
||||||
|
char *p = path.str;
|
||||||
|
for (; *p; ++p){
|
||||||
|
if (*p == '\\'){
|
||||||
|
*p = 0;
|
||||||
|
CreateDirectoryA(path.str, 0);
|
||||||
|
*p = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!CreateDirectoryA(path.str, 0)){
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_ClrDir:
|
||||||
|
{
|
||||||
|
String *d = &vm->temp;
|
||||||
|
copy_always(d, params[0].size+4);
|
||||||
|
if (d->str[d->size-1] != '\\'){
|
||||||
|
d->str[d->size++] = '\\';
|
||||||
|
}
|
||||||
|
d->str[d->size++] = '*';
|
||||||
|
d->str[d->size++] = 0;
|
||||||
|
d->str[d->size] = 0;
|
||||||
|
|
||||||
|
SHFILEOPSTRUCT fileop = {0};
|
||||||
|
fileop.wFunc = FO_DELETE;
|
||||||
|
fileop.pFrom = d->str;
|
||||||
|
fileop.fFlags = DONT_BUG_ME;
|
||||||
|
if (SHFileOperation(&fileop) != 0){
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Del:
|
||||||
|
{
|
||||||
|
if (!DeleteFileA(param[0].str)){
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_CD:
|
||||||
|
{
|
||||||
|
if (!SetCurrentDirectoryA(param[0].str)){
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Command:
|
||||||
|
{
|
||||||
|
systemf("%s", param[0].str);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Copy:
|
||||||
|
{
|
||||||
|
if (!CopyFileA(param[0], param[1], false)){
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Zip:
|
||||||
|
{
|
||||||
|
u32 length = GetCurrentDirectoryA(0, 0);
|
||||||
|
String *d = &vm->temp;
|
||||||
|
require_size(d, length+11);
|
||||||
|
d->size = GetCurrentDirectoryA(d->memory_size, d->str);
|
||||||
|
terminate_with_null(d);
|
||||||
|
|
||||||
|
i32 original_length = params[0].size;
|
||||||
|
remove_last_folder(¶ms[0]);
|
||||||
|
terminate_with_null(¶ms[0]);
|
||||||
|
if (SetCurrentDirectoryA(params[0].str)){
|
||||||
|
systemf("zip %s\\4tech_gobble.zip", d->str);
|
||||||
|
SetCurrentDirectoryA(d->str);
|
||||||
|
append_always(d, make_lit_string("\\gobble.zip"));
|
||||||
|
terminate_with_null(d);
|
||||||
|
|
||||||
|
if (!MoveFile(d->str, params[1].str)){
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
params[0].str[params[0].size-1] = '\\';
|
||||||
|
params[0].size = original_length;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_CopyAll:
|
||||||
|
{
|
||||||
|
require_size_preserve(¶ms[2], params[2].size+2);
|
||||||
|
params[2].str[params[2].size] = 0;
|
||||||
|
params[2].str[params[2].size+1] = 0;
|
||||||
|
|
||||||
|
require_size(&vm->temp, params[0].size+params[1].size+3);
|
||||||
|
copy_always(&vm->temp, params[0]);
|
||||||
|
copy_always(&vm->temp, make_lit_string("\\"));
|
||||||
|
copy_always(&vm->temp, params[1]);
|
||||||
|
vm->temp.str[vm->temp.size] = 0;
|
||||||
|
vm->temp.str[vm->temp.size+1] = 0;
|
||||||
|
|
||||||
|
SHFILEOPSTRUCT fileop = {0};
|
||||||
|
fileop.wFunc = FO_COPY;
|
||||||
|
fileop.pFrom = vm->temp.str;
|
||||||
|
fileop.pTo = param[2].str;
|
||||||
|
fileop.fFlags = DONT_BUG_ME | FOF_NORECURSION | FOF_FILESONLY;
|
||||||
|
if (SHFileOperation(&fileop) != 0){
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
default: InvalidCodePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef DONT_BUG_ME
|
||||||
|
|
||||||
|
#elif defined(IS_LINUX)
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
internal void
|
||||||
|
run_instruction_fm(Virtual_Machine_FM *vm, u16 op, String_Reg dest, u16 n, String *params){
|
||||||
|
switch(op){
|
||||||
|
case InstrFM_BeginTime:
|
||||||
|
case InstrFM_EndTime:
|
||||||
|
{
|
||||||
|
struct timespec spec;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||||
|
u64 time = (spec.tv_sec * 1000000) + (spec.tv_nsec / 1000);
|
||||||
|
if (op == InstrFM_BeginTime){
|
||||||
|
vm->time_start = time;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
u64 total = time - vm->time_start;
|
||||||
|
PRINT_TIME_FM(params[0].str);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_MovCWD:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
char *r = getcwd(d->str, d->memory_size);
|
||||||
|
if (r == d->str){
|
||||||
|
d->size = str_size(d->str);
|
||||||
|
}
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Push:
|
||||||
|
{
|
||||||
|
copy_always(&vm->stack_ptr[0], params[0]);
|
||||||
|
++vm->stack_ptr;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_StackLoad:
|
||||||
|
{
|
||||||
|
Assert((vm->stack_ptr - vm->stack_base) >= n);
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
String *s = vm->stack_ptr - n;
|
||||||
|
copy_always(d, *s);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Pop:
|
||||||
|
{
|
||||||
|
Assert((vm->stack_ptr - vm->stack_base) >= n);
|
||||||
|
vm->stack_ptr = vm->stack_ptr - n;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Mov:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
copy_always(d, params[0]);
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Leaf:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
copy_always(d, front_of_directory(params[0]));
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Cat:
|
||||||
|
{
|
||||||
|
String *d = &vm->reg[dest];
|
||||||
|
append_always(d, params[0]);
|
||||||
|
terminate_with_null(d);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_SlashFix:break;
|
||||||
|
|
||||||
|
case InstrFM_MkDir:
|
||||||
|
{
|
||||||
|
systemf("mkdir -p %s", params[0].str);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_ClrDir:
|
||||||
|
{
|
||||||
|
systemf("rm -rf %s*", params[0].str);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Del:
|
||||||
|
{
|
||||||
|
systemf("rm %s", params[0].str);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_CD:
|
||||||
|
{
|
||||||
|
chdir(params[0].str);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Command:
|
||||||
|
{
|
||||||
|
systemf("%s", params[0].str);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Copy:
|
||||||
|
{
|
||||||
|
systemf("cp %s %s", params[0].str, params[1].str);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_Zip:
|
||||||
|
{
|
||||||
|
String *d = &vm->temp;
|
||||||
|
char *r = getcwd(d->str, d->memory_size);
|
||||||
|
|
||||||
|
if (r == d->str){
|
||||||
|
d->size = str_size(d->str);
|
||||||
|
|
||||||
|
i32 original_length = params[0].size;
|
||||||
|
remove_last_folder(¶ms[0]);
|
||||||
|
terminate_with_null(¶ms[0]);
|
||||||
|
if (chdir(params[0].str)){
|
||||||
|
char *folder = params[0].str + params[0].size + 1;
|
||||||
|
systemf("zip -r %s %s", params[1].str, folder);
|
||||||
|
chdir(d->str);
|
||||||
|
terminate_with_null(d);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
params[0].str[params[0].size-1] = '\\';
|
||||||
|
params[0].size = original_length;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// TODO(allen): error.
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case InstrFM_CopyAll:
|
||||||
|
{
|
||||||
|
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error No implementation for run_instruction_fm on this OS.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Instruction emitter
|
||||||
|
struct Emitter_FM{
|
||||||
|
u8 *buffer;
|
||||||
|
umem pos, max;
|
||||||
|
};
|
||||||
|
Emitter_FM global_emitter_fm = {0};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
init_fm(void *buffer, umem length){
|
||||||
|
global_emitter_fm.buffer = (u8*)buffer;
|
||||||
|
global_emitter_fm.pos = 0;
|
||||||
|
global_emitter_fm.max = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
execute_fm(){
|
||||||
|
execute_instructions_fm(global_emitter_fm.buffer, global_emitter_fm.pos);
|
||||||
|
global_emitter_fm.pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
emit_u16_fm(u16 x){
|
||||||
|
Assert(global_emitter_fm.pos+2 <= global_emitter_fm.max);
|
||||||
|
*(u16*)(global_emitter_fm.buffer + global_emitter_fm.pos) = x;
|
||||||
|
global_emitter_fm.pos += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
emit_strlit_fm(char *str, u16 len){
|
||||||
|
u16 full_len = len+1;
|
||||||
|
u16 mem_len = (full_len+1)&(~1);
|
||||||
|
Assert(global_emitter_fm.pos+mem_len <= global_emitter_fm.max);
|
||||||
|
u8 *dst = global_emitter_fm.buffer + global_emitter_fm.pos;
|
||||||
|
u16 i = 0;
|
||||||
|
for (; i < len; ++i){
|
||||||
|
dst[i] = str[i];
|
||||||
|
}
|
||||||
|
dst[i] = 0;
|
||||||
|
global_emitter_fm.pos += mem_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct String_Param{
|
||||||
|
b32 is_literal;
|
||||||
|
String_Reg reg;
|
||||||
|
u16 len;
|
||||||
|
char *n;
|
||||||
|
};
|
||||||
|
internal String_Param
|
||||||
|
reg_fm(String_Reg reg){
|
||||||
|
String_Param result = {0};
|
||||||
|
result.reg = reg;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
internal String_Param
|
||||||
|
lit_fm(char *n){
|
||||||
|
String_Param result = {0};
|
||||||
|
result.is_literal = true;
|
||||||
|
result.len = str_size(n);
|
||||||
|
result.n = n;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
internal String_Param
|
||||||
|
litn_fm(char *n, u16 len){
|
||||||
|
String_Param result = {0};
|
||||||
|
result.is_literal = true;
|
||||||
|
result.len = len;
|
||||||
|
result.n = n;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
internal void
|
||||||
|
emit_param_fm(String_Param n){
|
||||||
|
if (n.is_literal){
|
||||||
|
emit_strlit_fm(n.n, n.len);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
emit_u16_fm(n.reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal void
|
||||||
|
param_flag_fm(u16 *ins, String_Param n, u16 param_i){
|
||||||
|
local_persist u16 flags[] = {
|
||||||
|
InstrFM_LiteralParam1,
|
||||||
|
InstrFM_LiteralParam2,
|
||||||
|
InstrFM_LiteralParam3,
|
||||||
|
};
|
||||||
|
if (n.is_literal){
|
||||||
|
*ins |= flags[param_i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
begin_time_fm(){
|
||||||
|
u16 ins = InstrFM_BeginTime;
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
end_time_fm(String_Param n){
|
||||||
|
u16 ins = InstrFM_EndTime;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
push_fm(String_Param n){
|
||||||
|
u16 ins = InstrFM_Push;
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
stack_load_fm(String_Reg reg, u16 index){
|
||||||
|
u16 ins = InstrFM_StackLoad;
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(reg);
|
||||||
|
emit_u16_fm(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
pop_fm(u16 count){
|
||||||
|
u16 ins = InstrFM_Pop;
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
mov_cwd_fm(String_Reg reg){
|
||||||
|
u16 ins = InstrFM_MovCWD;
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
mov_fm(String_Reg reg, String_Param n){
|
||||||
|
u16 ins = InstrFM_Mov;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(reg);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
leaf_fm(String_Reg reg, String_Param n){
|
||||||
|
u16 ins = InstrFM_Leaf;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(reg);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
path_fm(String_Reg reg, String_Param n){
|
||||||
|
u16 ins = InstrFM_Path;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(reg);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
cat_fm(String_Reg reg, String_Param n){
|
||||||
|
u16 ins = InstrFM_Cat;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(reg);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
slash_fix_fm(String_Reg reg, String_Param n){
|
||||||
|
u16 ins = InstrFM_SlashFix;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_u16_fm(reg);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
mkdir_fm(String_Param n){
|
||||||
|
u16 ins = InstrFM_MkDir;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
clrdir_fm(String_Param n){
|
||||||
|
u16 ins = InstrFM_ClrDir;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
del_fm(String_Param n){
|
||||||
|
u16 ins = InstrFM_Del;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
copy_fm(String_Param s, String_Param d){
|
||||||
|
u16 ins = InstrFM_Copy;
|
||||||
|
param_flag_fm(&ins, s, 0);
|
||||||
|
param_flag_fm(&ins, d, 1);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(s);
|
||||||
|
emit_param_fm(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
copy_all_fm(String_Param s, String_Param d, String_Param p){
|
||||||
|
u16 ins = InstrFM_CopyAll;
|
||||||
|
param_flag_fm(&ins, s, 0);
|
||||||
|
param_flag_fm(&ins, d, 1);
|
||||||
|
param_flag_fm(&ins, p, 2);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(s);
|
||||||
|
emit_param_fm(d);
|
||||||
|
emit_param_fm(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
zip_fm(String_Param s, String_Param d){
|
||||||
|
u16 ins = InstrFM_Copy;
|
||||||
|
param_flag_fm(&ins, s, 0);
|
||||||
|
param_flag_fm(&ins, d, 1);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(s);
|
||||||
|
emit_param_fm(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
cd_fm(String_Param n){
|
||||||
|
u16 ins = InstrFM_Copy;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
command_fm(String_Param n){
|
||||||
|
u16 ins = InstrFM_Command;
|
||||||
|
param_flag_fm(&ins, n, 0);
|
||||||
|
emit_u16_fm(ins);
|
||||||
|
emit_param_fm(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// OLD VERSION
|
||||||
|
#if 0
|
||||||
#if defined(IS_WINDOWS)
|
#if defined(IS_WINDOWS)
|
||||||
# define ONLY_WINDOWS(x) x
|
# define ONLY_WINDOWS(x) x
|
||||||
# define ONLY_LINUX(x) (void)0
|
# define ONLY_LINUX(x) (void)0
|
||||||
|
@ -60,15 +885,9 @@ static char platform_correct_slash = '\\';
|
||||||
static char platform_correct_slash = '/';
|
static char platform_correct_slash = '/';
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define ONLY_WINDOWS(x) (void)0
|
# error File moving is not setup on this OS.
|
||||||
# define ONLY_LINUX(x) (void)0
|
|
||||||
|
|
||||||
#define SLASH "/"
|
|
||||||
static char platform_correct_slash = '/';
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static char SF_CMD[4096];
|
static char SF_CMD[4096];
|
||||||
static i32 error_state = 0;
|
static i32 error_state = 0;
|
||||||
static i32 prev_error = 0;
|
static i32 prev_error = 0;
|
||||||
|
@ -442,5 +1261,7 @@ zip(char *parent, char *folder, char *file){
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
312
meta/build.cpp
312
meta/build.cpp
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
4coder development build rule.
|
The 4coder build and package rules.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
@ -21,10 +21,12 @@
|
||||||
|
|
||||||
#define IS_64BIT
|
#define IS_64BIT
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define LLU_CAST(n) (long long unsigned int)(n)
|
#define LLU_CAST(n) (long long unsigned int)(n)
|
||||||
|
|
||||||
#define BEGIN_TIME_SECTION() uint64_t start = get_time()
|
#define BEGIN_TIME_SECTION() uint64_t start = get_time()
|
||||||
#define END_TIME_SECTION(n) uint64_t total = get_time() - start; printf("%-20s: %.2llu.%.6llu\n", (n), LLU_CAST(total/1000000), LLU_CAST(total%1000000));
|
#define END_TIME_SECTION(n) uint64_t total = get_time() - start; printf("%-20s: %.2llu.%.6llu\n", (n), LLU_CAST(total/1000000), LLU_CAST(total%1000000));
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// 4coder specific
|
// 4coder specific
|
||||||
|
@ -145,6 +147,7 @@ init_build_line(Build_Line *line){
|
||||||
|
|
||||||
#define CL_X86 "-MACHINE:X86"
|
#define CL_X86 "-MACHINE:X86"
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void
|
static void
|
||||||
build_cl(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){
|
build_cl(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){
|
||||||
Build_Line line;
|
Build_Line line;
|
||||||
|
@ -239,7 +242,107 @@ build_cl(u32 flags, char *code_path, char *code_file, char *out_path, char *out_
|
||||||
systemf("%scl %s \"%s\\%s\" /Fe%s /link /INCREMENTAL:NO %s", line_prefix.build_options, line.build_options, code_path, code_file, out_file, link_line.build_options);
|
systemf("%scl %s \"%s\\%s\" /Fe%s /link /INCREMENTAL:NO %s", line_prefix.build_options, line.build_options, code_path, code_file, out_file, link_line.build_options);
|
||||||
popdir(temp);
|
popdir(temp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
build_cl(u32 flags){
|
||||||
|
push_fm(reg_fm(0));
|
||||||
|
push_fm(reg_fm(1));
|
||||||
|
push_fm(reg_fm(2));
|
||||||
|
|
||||||
|
mov_fm(0, lit_fm(""));
|
||||||
|
mov_fm(1, lit_fm(""));
|
||||||
|
mov_fm(2, lit_fm(""));
|
||||||
|
|
||||||
|
// line prefix
|
||||||
|
if (flags & X86){
|
||||||
|
cat_fm(0, lit_fm("SETUP_CLX86 & "));
|
||||||
|
}
|
||||||
|
|
||||||
|
// line
|
||||||
|
if (flags & OPTS){
|
||||||
|
cat_fm(1, lit_fm(" "CL_OPTS));
|
||||||
|
}
|
||||||
|
if (flags & X86){
|
||||||
|
cat_fm(1, lit_fm(" /DFTECH_32_BIT"));
|
||||||
|
}
|
||||||
|
if (flags & INCLUDES){
|
||||||
|
cat_fm(1, lit_fm(" "CL_INCLUDES));
|
||||||
|
}
|
||||||
|
if (flags & SITE_INCLUDES){
|
||||||
|
cat_fm(1, lit_fm(" "CL_SITE_INCLUDES));
|
||||||
|
}
|
||||||
|
if (flags & LIBS){
|
||||||
|
if (flags & X86){
|
||||||
|
cat_fm(1, lit_fm(" "CL_LIBS_X86));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
cat_fm(1, lit_fm(" "CL_LIBS_X64));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flags & ICON){
|
||||||
|
cat_fm(1, lit_fm(" "CL_ICON));
|
||||||
|
}
|
||||||
|
if (flags & DEBUG_INFO){
|
||||||
|
cat_fm(1, lit_fm(" /Zi"));
|
||||||
|
}
|
||||||
|
if (flags & OPTIMIZATION){
|
||||||
|
cat_fm(1, lit_fm(" /O2"));
|
||||||
|
}
|
||||||
|
if (flags & SHARED_CODE){
|
||||||
|
cat_fm(1, lit_fm(" /LD"));
|
||||||
|
}
|
||||||
|
if (flags & SUPER){
|
||||||
|
cat_fm(1, lit_fm(" /DFRED_SUPER"));
|
||||||
|
}
|
||||||
|
if (flags & INTERNAL){
|
||||||
|
cat_fm(1, lit_fm(" /DFRED_INTERNAL"));
|
||||||
|
}
|
||||||
|
if (flags & KEEP_ASSERT){
|
||||||
|
cat_fm(1, lit_fm(" /DFRED_KEEP_ASSERT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// link line
|
||||||
|
if (flags & X86){
|
||||||
|
cat_fm(2, lit_fm(" "CL_X86));
|
||||||
|
}
|
||||||
|
if (flags & DEBUG_INFO){
|
||||||
|
cat_fm(2, lit_fm(" /DEBUG"));
|
||||||
|
}
|
||||||
|
if (flags & SHARED_CODE){
|
||||||
|
stack_load_fm(3, 1);
|
||||||
|
cat_fm(2, lit_fm(" /OPT:REF "));
|
||||||
|
cat_fm(2, reg_fm(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
stack_load_fm(4, 2);
|
||||||
|
leaf_fm(4, reg_fm(4));
|
||||||
|
|
||||||
|
// prefix
|
||||||
|
mov_fm(3, reg_fm(0));
|
||||||
|
// compiler
|
||||||
|
cat_fm(3, lit_fm("cl "));
|
||||||
|
cat_fm(3, reg_fm(1));
|
||||||
|
// input file
|
||||||
|
cat_fm(3, lit_fm(" \""));
|
||||||
|
stack_load_fm(0, 3);
|
||||||
|
cat_fm(3, reg_fm(0));
|
||||||
|
// output name
|
||||||
|
cat_fm(3, lit_fm("\" /Fe"));
|
||||||
|
cat_fm(3, reg_fm(4));
|
||||||
|
// linker
|
||||||
|
cat_fm(3, lit_fm(" /link /INCREMENTAL:NO "));
|
||||||
|
cat_fm(3, reg_fm(2));
|
||||||
|
|
||||||
|
stack_load_fm(4, 2);
|
||||||
|
path_fm(4, reg_fm(4));
|
||||||
|
mov_cwd_fm(0);
|
||||||
|
cd_fm(reg_fm(4));
|
||||||
|
command_fm(reg_fm(3));
|
||||||
|
cd_fm(reg_fm(0));
|
||||||
|
|
||||||
|
pop_fm(3);
|
||||||
|
}
|
||||||
|
|
||||||
#define GCC_OPTS \
|
#define GCC_OPTS \
|
||||||
"-Wno-write-strings -D_GNU_SOURCE -fPIC " \
|
"-Wno-write-strings -D_GNU_SOURCE -fPIC " \
|
||||||
|
@ -257,6 +360,7 @@ build_cl(u32 flags, char *code_path, char *code_file, char *out_path, char *out_
|
||||||
"-L/usr/local/lib -lX11 -lpthread -lm -lrt " \
|
"-L/usr/local/lib -lX11 -lpthread -lm -lrt " \
|
||||||
"-lGL -ldl -lXfixes -lfreetype -lfontconfig"
|
"-lGL -ldl -lXfixes -lfreetype -lfontconfig"
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void
|
static void
|
||||||
build_gcc(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){
|
build_gcc(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){
|
||||||
Build_Line line;
|
Build_Line line;
|
||||||
|
@ -330,18 +434,129 @@ build_gcc(u32 flags, char *code_path, char *code_file, char *out_path, char *out
|
||||||
systemf("g++ %s -o %s", line.build_options, out_file);
|
systemf("g++ %s -o %s", line.build_options, out_file);
|
||||||
popdir(temp);
|
popdir(temp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){
|
build_gcc(u32 flags){
|
||||||
#if defined(IS_CL)
|
push_fm(reg_fm(0));
|
||||||
build_cl(flags, code_path, code_file, out_path, out_file, exports);
|
push_fm(reg_fm(1));
|
||||||
#elif defined(IS_GCC)
|
push_fm(reg_fm(2));
|
||||||
build_gcc(flags, code_path, code_file, out_path, out_file, exports);
|
|
||||||
#else
|
mov_fm(0, lit_fm("g++ "));
|
||||||
#error The build rule for this compiler is not ready
|
|
||||||
|
if (flags & X86){
|
||||||
|
cat_fm(0, lit_fm(GCC_X86));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
cat_fm(0, lit_fm(GCC_X64));
|
||||||
|
}
|
||||||
|
if (flags & OPTS){
|
||||||
|
cat_fm(0, lit_fm(GCC_OPTS));
|
||||||
|
}
|
||||||
|
if (flags & INCLUDES){
|
||||||
|
// TODO(allen): Abstract this out.
|
||||||
|
#if defined(IS_LINUX)
|
||||||
|
i32 size = 0;
|
||||||
|
char freetype_include[512];
|
||||||
|
FILE *file = popen("pkg-config --cflags freetype2", "r");
|
||||||
|
if (file != 0){
|
||||||
|
fgets(freetype_include, sizeof(freetype_include), file);
|
||||||
|
size = strlen(freetype_include);
|
||||||
|
freetype_include[--size] = 0;
|
||||||
|
pclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
cat_fm(0, lit_fm(GCC_INCLUDES" "));
|
||||||
|
cat_fm(0, litn_fm(freetype_include, size));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
if (flags & SITE_INCLUDES){
|
||||||
|
cat_fm(0, lit_fm(GCC_SITE_INCLUDES));
|
||||||
|
}
|
||||||
|
if (flags & DEBUG_INFO){
|
||||||
|
cat_fm(0, lit_fm("-g -O0"));
|
||||||
|
}
|
||||||
|
if (flags & OPTIMIZATION){
|
||||||
|
cat_fm(0, lit_fm("-O3"));
|
||||||
|
}
|
||||||
|
if (flags & SHARED_CODE){
|
||||||
|
cat_fm(0, lit_fm("-shared"));
|
||||||
|
}
|
||||||
|
if (flags & SUPER){
|
||||||
|
cat_fm(0, lit_fm("-DFRED_SUPER"));
|
||||||
|
}
|
||||||
|
if (flags & INTERNAL){
|
||||||
|
cat_fm(0, lit_fm("-DFRED_INTERNAL"));
|
||||||
|
}
|
||||||
|
if (flags & KEEP_ASSERT){
|
||||||
|
cat_fm(0, lit_fm("-DFRED_KEEP_ASSERT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
cat_fm(0, lit_fm(" "));
|
||||||
|
stack_load_fm(1, 3);
|
||||||
|
cat_fm(0, reg_fm(1));
|
||||||
|
|
||||||
|
if (flags & LIBS){
|
||||||
|
cat_fm(0, lit_fm(GCC_LIBS));
|
||||||
|
}
|
||||||
|
|
||||||
|
stack_load_fm(1, 2);
|
||||||
|
leaf_fm(1, reg_fm(1));
|
||||||
|
cat_fm(0, lit_fm(" -o "));
|
||||||
|
cat_fm(0, reg_fm(1));
|
||||||
|
|
||||||
|
pop_fm(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(IS_CL)
|
||||||
|
#define build build_cl
|
||||||
|
#elif defined(IS_GCC)
|
||||||
|
#define build build_gcc
|
||||||
|
#else
|
||||||
|
#error The build rule for this compiler is not ready.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
buildsuper(b32 x86_build){
|
||||||
|
mov_cwd_fm(3);
|
||||||
|
cd_fm(reg_fm(1));
|
||||||
|
#if defined(IS_CL)
|
||||||
|
{
|
||||||
|
if (x86_build){
|
||||||
|
mov_fm(4, lit_fm("setup_clx86 & "));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
mov_fm(4, lit_fm(""));
|
||||||
|
}
|
||||||
|
cat_fm(4, lit_fm("call \""));
|
||||||
|
cat_fm(4, reg_fm(0));
|
||||||
|
if (x86_build){
|
||||||
|
cat_fm(4, lit_fm("buildsuper_x86.bat\" "));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
cat_fm(4, lit_fm("buildsuper.bat\" \""));
|
||||||
|
}
|
||||||
|
cat_fm(4, reg_fm(2));
|
||||||
|
cat_fm(4, lit_fm("\""));
|
||||||
|
command_fm(reg_fm(4));
|
||||||
|
}
|
||||||
|
#elif defined(IS_GCC)
|
||||||
|
{
|
||||||
|
mov_fm(4, lit_fm("\""));
|
||||||
|
cat_fm(4, reg_fm(0));
|
||||||
|
cat_fm(4, lit_fm("/buildsuper.sh\" \""));
|
||||||
|
cat_fm(4, reg_fm(2));
|
||||||
|
cat_fm(4, lit_fm("\""));
|
||||||
|
command_fm(reg_fm(4));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error The build rule for this compiler is not ready.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cd_fm(reg_fm(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void
|
static void
|
||||||
buildsuper(char *code_path, char *out_path, char *filename, b32 x86_build){
|
buildsuper(char *code_path, char *out_path, char *filename, b32 x86_build){
|
||||||
Temp_Dir temp = pushdir(out_path);
|
Temp_Dir temp = pushdir(out_path);
|
||||||
|
@ -364,6 +579,7 @@ buildsuper(char *code_path, char *out_path, char *filename, b32 x86_build){
|
||||||
#endif
|
#endif
|
||||||
popdir(temp);
|
popdir(temp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(IS_WINDOWS)
|
#if defined(IS_WINDOWS)
|
||||||
#define PLAT_LAYER "win32_4ed.cpp"
|
#define PLAT_LAYER "win32_4ed.cpp"
|
||||||
|
@ -379,39 +595,54 @@ buildsuper(char *code_path, char *out_path, char *filename, b32 x86_build){
|
||||||
static void
|
static void
|
||||||
fsm_generator(char *cdir){
|
fsm_generator(char *cdir){
|
||||||
{
|
{
|
||||||
DECL_STR(file, "meta/fsm_table_generator.cpp");
|
begin_time_fm();
|
||||||
DECL_STR(dir, META_DIR);
|
mov_fm(0, lit_fm(cdir));
|
||||||
|
cat_fm(0, lit_fm("/meta/fsm_table_generator.cpp"));
|
||||||
BEGIN_TIME_SECTION();
|
slash_fix_fm(0, reg_fm(0));
|
||||||
build(OPTS | DEBUG_INFO, cdir, file, dir, "fsmgen", 0);
|
slash_fix_fm(1, lit_fm(META_DIR));
|
||||||
END_TIME_SECTION("build fsm generator");
|
mov_fm(2, lit_fm(""));
|
||||||
|
build(OPTS | DEBUG_INFO);
|
||||||
|
end_time_fm(lit_fm("build fsm generator"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_error == 0){
|
if (prev_error == 0){
|
||||||
DECL_STR(cmd, META_DIR"/fsmgen");
|
begin_time_fm();
|
||||||
BEGIN_TIME_SECTION();
|
mov_fm(1, lit_fm(cdir));
|
||||||
execute_in_dir(cdir, cmd, 0);
|
mov_cwd_fm(0);
|
||||||
END_TIME_SECTION("run fsm generator");
|
cd_fm(reg_fm(1));
|
||||||
|
mov_fm(2, lit_fm(META_DIR"/fsmgen"));
|
||||||
|
command_fm(reg_fm(2));
|
||||||
|
cd_fm(reg_fm(0));
|
||||||
|
end_time_fm(lit_fm("run fsm generator"));
|
||||||
}
|
}
|
||||||
|
execute_fm();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
metagen(char *cdir){
|
metagen(char *cdir){
|
||||||
{
|
{
|
||||||
DECL_STR(file, "meta/4ed_metagen.cpp");
|
begin_time_fm();
|
||||||
DECL_STR(dir, META_DIR);
|
mov_fm(0, lit_fm(cdir));
|
||||||
|
cat_fm(0, lit_fm("/meta/4ed_metagen.cpp"));
|
||||||
BEGIN_TIME_SECTION();
|
slash_fix_fm(0, reg_fm(0));
|
||||||
build(OPTS | INCLUDES | DEBUG_INFO, cdir, file, dir, "metagen", 0);
|
slash_fix_fm(1, lit_fm(META_DIR));
|
||||||
END_TIME_SECTION("build metagen");
|
mov_fm(2, lit_fm(""));
|
||||||
|
build(OPTS | INCLUDES | DEBUG_INFO);
|
||||||
|
end_time_fm(lit_fm("build metagen"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_error == 0){
|
{
|
||||||
DECL_STR(cmd, META_DIR "/metagen");
|
begin_time_fm();
|
||||||
BEGIN_TIME_SECTION();
|
mov_fm(1, lit_fm(cdir));
|
||||||
execute_in_dir(cdir, cmd, 0);
|
mov_cwd_fm(0);
|
||||||
END_TIME_SECTION("run metagen");
|
cd_fm(reg_fm(1));
|
||||||
|
mov_fm(2, lit_fm(META_DIR"/metagen"));
|
||||||
|
command_fm(reg_fm(2));
|
||||||
|
cd_fm(reg_fm(0));
|
||||||
|
end_time_fm(lit_fm("run metagen"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
execute_fm();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
|
@ -424,43 +655,40 @@ enum{
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_buildsuper(char *cdir, i32 custom_option, u32 flags){
|
do_buildsuper(char *cdir, i32 custom_option, u32 flags){
|
||||||
char space[1024];
|
begin_time_fm();
|
||||||
String str = make_fixed_width_string(space);
|
|
||||||
|
|
||||||
BEGIN_TIME_SECTION();
|
b32 x86_build = ((flags & X86) != 0);
|
||||||
|
|
||||||
|
mov_fm(0, lit_fm(cdir));
|
||||||
|
|
||||||
switch (custom_option){
|
switch (custom_option){
|
||||||
case Custom_Default:
|
case Custom_Default:
|
||||||
{
|
{
|
||||||
copy_sc(&str, "../code/4coder_default_bindings.cpp");
|
slash_fix_fm(2, lit_fm("../code/4coder_default_bindings.cpp"));
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case Custom_Experiments:
|
case Custom_Experiments:
|
||||||
{
|
{
|
||||||
copy_sc(&str, "../code/power/4coder_experiments.cpp");
|
slash_fix_fm(2, lit_fm("../code/power/4coder_experiments.cpp"));
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case Custom_Casey:
|
case Custom_Casey:
|
||||||
{
|
{
|
||||||
copy_sc(&str, "../code/power/4coder_casey.cpp");
|
slash_fix_fm(2, lit_fm("../code/power/4coder_casey.cpp"));
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case Custom_ChronalVim:
|
case Custom_ChronalVim:
|
||||||
{
|
{
|
||||||
copy_sc(&str, "../4vim/4coder_chronal.cpp");
|
slash_fix_fm(2, lit_fm("../4vim/4coder_chronal.cpp"));
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
terminate_with_null(&str);
|
|
||||||
|
|
||||||
b32 x86_build = false;
|
|
||||||
if (flags & X86){
|
|
||||||
x86_build = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DECL_STR(dir, BUILD_DIR);
|
DECL_STR(dir, BUILD_DIR);
|
||||||
buildsuper(cdir, dir, str.str, x86_build);
|
buildsuper(cdir, dir, str.str, x86_build);
|
||||||
|
|
||||||
END_TIME_SECTION("build custom");
|
end_time_fm("build custom");
|
||||||
|
execute_fm();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue