Initial commit
This commit is contained in:
commit
d244528dfb
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
tbuild
|
||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "tomlc99"]
|
||||
path = tomlc99
|
||||
url = https://github.com/cktan/tomlc99
|
27
LICENSE.md
Normal file
27
LICENSE.md
Normal file
@ -0,0 +1,27 @@
|
||||
# DON'T BE A DICK PUBLIC LICENSE
|
||||
|
||||
> Version 1.1, December 2016
|
||||
|
||||
> Copyright (C) 2022 Slendi <slendi@socopon.com>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document.
|
||||
|
||||
> DON'T BE A DICK PUBLIC LICENSE
|
||||
> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
1. Do whatever you like with the original work, just don't be a dick.
|
||||
|
||||
Being a dick includes - but is not limited to - the following instances:
|
||||
|
||||
1a. Outright copyright infringement - Don't just copy this and change the name.
|
||||
1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
|
||||
1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
|
||||
|
||||
2. If you become rich through modifications, related works/services, or supporting the original work,
|
||||
share the love. Only a dick would make loads off this work and not buy the original work's
|
||||
creator(s) a pint.
|
||||
|
||||
3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
|
||||
you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.
|
||||
|
BIN
RedSeaGen.exe
Normal file
BIN
RedSeaGen.exe
Normal file
Binary file not shown.
4
build.sh
Executable file
4
build.sh
Executable file
@ -0,0 +1,4 @@
|
||||
cd tomlc99
|
||||
make
|
||||
cd ..
|
||||
cc tomlc99/toml.o main.c -o tbuild
|
741
main.c
Normal file
741
main.c
Normal file
@ -0,0 +1,741 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "tomlc99/toml.h"
|
||||
|
||||
// FIXME: This is hardcoded, fix it.
|
||||
char *python_interpreter_path = "/usr/local/bin/python3";
|
||||
|
||||
bool can_run_command(const char *cmd) {
|
||||
if(strchr(cmd, '/')) {
|
||||
return access(cmd, X_OK)==0;
|
||||
}
|
||||
const char *path = getenv("PATH");
|
||||
if(!path) return false;
|
||||
char *buf = malloc(strlen(path)+strlen(cmd)+3);
|
||||
if(!buf) return false;
|
||||
for(; *path; ++path) {
|
||||
char *p = buf;
|
||||
for(; *path && *path!=':'; ++path,++p)
|
||||
*p = *path;
|
||||
if(p==buf) *p++='.';
|
||||
if(p[-1]!='/') *p++='/';
|
||||
strcpy(p, cmd);
|
||||
if(access(buf, X_OK)==0) {
|
||||
free(buf);
|
||||
return true;
|
||||
}
|
||||
if(!*path) break;
|
||||
}
|
||||
free(buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
bool copy_directory(const char *src_path, const char *dest_path) {
|
||||
DIR *src_dir = opendir(src_path);
|
||||
if (src_dir == NULL) {
|
||||
// Failed to open source directory
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create destination directory if it doesn't exist
|
||||
mkdir(dest_path, 0755);
|
||||
|
||||
// Copy files and directories from source to destination
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(src_dir)) != NULL) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||
// Skip "." and ".." directories
|
||||
continue;
|
||||
}
|
||||
|
||||
char src_file_path[BUFFER_SIZE];
|
||||
snprintf(src_file_path, BUFFER_SIZE, "%s/%s", src_path, entry->d_name);
|
||||
|
||||
char dest_file_path[BUFFER_SIZE];
|
||||
snprintf(dest_file_path, BUFFER_SIZE, "%s/%s", dest_path, entry->d_name);
|
||||
|
||||
struct stat src_file_stat;
|
||||
stat(src_file_path, &src_file_stat);
|
||||
|
||||
if (S_ISDIR(src_file_stat.st_mode)) {
|
||||
// Recursively copy directories
|
||||
if (!copy_directory(src_file_path, dest_file_path)) {
|
||||
return false;
|
||||
}
|
||||
} else if (S_ISREG(src_file_stat.st_mode)) {
|
||||
// Copy regular files
|
||||
FILE *src_file = fopen(src_file_path, "rb");
|
||||
if (src_file == NULL) {
|
||||
// Failed to open source file
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *dest_file = fopen(dest_file_path, "wb");
|
||||
if (dest_file == NULL) {
|
||||
// Failed to open destination file
|
||||
fclose(src_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy file contents
|
||||
char buffer[BUFFER_SIZE];
|
||||
size_t bytes_read;
|
||||
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, src_file)) > 0) {
|
||||
fwrite(buffer, 1, bytes_read, dest_file);
|
||||
}
|
||||
|
||||
fclose(src_file);
|
||||
fclose(dest_file);
|
||||
} else {
|
||||
// Skip other file types
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(src_dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear_directory(char const *path) {
|
||||
DIR *dir = opendir(path);
|
||||
if (dir == NULL) {
|
||||
// Unable to open the directory
|
||||
perror("opendir");
|
||||
return;
|
||||
}
|
||||
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
// Skip "." and ".." entries
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the full path of the entry
|
||||
char entry_path[1024];
|
||||
snprintf(entry_path, sizeof(entry_path), "%s/%s", path, entry->d_name);
|
||||
|
||||
// Check if the entry is a directory
|
||||
struct stat entry_stat;
|
||||
if (stat(entry_path, &entry_stat) != 0) {
|
||||
perror("stat");
|
||||
continue;
|
||||
}
|
||||
if (S_ISDIR(entry_stat.st_mode)) {
|
||||
// Remove the directory recursively
|
||||
clear_directory(entry_path);
|
||||
if (rmdir(entry_path) != 0) {
|
||||
perror("rmdir");
|
||||
}
|
||||
} else {
|
||||
// Remove the entry
|
||||
if (unlink(entry_path) != 0) {
|
||||
perror("unlink");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
#define MANIFEST_FNAME "tos_project.toml"
|
||||
|
||||
char* find_project_root(void)
|
||||
{
|
||||
char* result = NULL;
|
||||
|
||||
// Get the current working directory
|
||||
char cwd[1024];
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if the current working directory contains the file "tos_project.toml"
|
||||
size_t file_path_len = strlen(cwd) + strlen("/tos_project.toml") + 1;
|
||||
char file_path[file_path_len];
|
||||
snprintf(file_path, file_path_len, "%s/tos_project.toml", cwd);
|
||||
|
||||
if (access(file_path, F_OK) == 0) {
|
||||
// The file exists, so we can return the path to the directory containing it
|
||||
result = malloc(strlen(cwd) + 1);
|
||||
strncpy(result, cwd, strlen(cwd) + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
// The file does not exist in the current working directory, so we need to search backwards
|
||||
size_t len = strlen(cwd);
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
if (cwd[i] == '/') {
|
||||
// We found a directory separator, so we can check if the parent directory contains the file
|
||||
cwd[i] = '\0';
|
||||
snprintf(file_path, file_path_len, "%s/tos_project.toml", cwd);
|
||||
|
||||
if (access(file_path, F_OK) == 0) {
|
||||
// The file exists, so we can return the path to the parent directory containing it
|
||||
result = malloc(strlen(cwd) + 1);
|
||||
strncpy(result, cwd, strlen(cwd) + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define SAMPLE_MANIFEST "[General]\n" \
|
||||
"Name=\"%s\"\n" \
|
||||
"Author=\"%s\"\n" \
|
||||
"Version=\"0.1\"\n" \
|
||||
"\n" \
|
||||
"[Dependencies]\n"
|
||||
|
||||
typedef struct project_manifest {
|
||||
char *name, *author, *version;
|
||||
// FIXME: Add dependencies.
|
||||
} project_manifest;
|
||||
|
||||
void free_manifest(project_manifest *manifest) {
|
||||
free(manifest->name);
|
||||
free(manifest->author);
|
||||
free(manifest->version);
|
||||
}
|
||||
|
||||
project_manifest* load_manifest(char const *path) {
|
||||
FILE* fp;
|
||||
char errbuf[200];
|
||||
|
||||
fp = fopen(path, "r");
|
||||
if (!fp) {
|
||||
fputs("Error: Cannot load manifest file: Cannot open file.\n", stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
project_manifest *new = calloc(1, sizeof(project_manifest));
|
||||
|
||||
toml_table_t *conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||
fclose(fp);
|
||||
if (!conf) {
|
||||
fprintf(stderr, "Error: Cannot load manifest file: Cannot parse file.\n", errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
toml_table_t *general = toml_table_in(conf, "General");
|
||||
if (!general) {
|
||||
fprintf(stderr, "Error: Cannot load manifest file: Cannot find [General] table.\n", errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
toml_datum_t name = toml_string_in(general, "Name");
|
||||
if (!name.ok) {
|
||||
fprintf(stderr, "Error: Cannot load manifest file: Cannot find Name field.\n", errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
toml_datum_t author = toml_string_in(general, "Author");
|
||||
if (!author.ok) {
|
||||
fprintf(stderr, "Error: Cannot load manifest file: Cannot find Author field.\n", errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
toml_datum_t version = toml_string_in(general, "Version");
|
||||
if (!version.ok) {
|
||||
fprintf(stderr, "Error: Cannot load manifest file: Cannot find Version field.\n", errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new->name = name.u.s;
|
||||
new->author = author.u.s;
|
||||
new->version = version.u.s;
|
||||
|
||||
// FIXME: Add dependencies.
|
||||
|
||||
toml_free(conf);
|
||||
|
||||
printf("%s, %s, %s\n", new->name, new->author, new->version);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
char buffer_text_format[2048];
|
||||
char *text_format(char const *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf(buffer_text_format, format, args);
|
||||
va_end(args);
|
||||
return buffer_text_format;
|
||||
}
|
||||
|
||||
char *get_username(void) {
|
||||
#if defined(_WIN32)
|
||||
// FIXME: This leaks memory.
|
||||
|
||||
TCHAR infoBuf[105];
|
||||
DWORD bufCharCount = 105;
|
||||
if( !GetUserName( infoBuf, &bufCharCount ) )
|
||||
printError( TEXT("GetUserName") );
|
||||
|
||||
char *c_szText[105];
|
||||
wcstombs(c_szText, infoBuf, wcslen(infoBuf) + 1);
|
||||
return c_szText;
|
||||
#else
|
||||
uid_t uid = geteuid();
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
if (pw == NULL)
|
||||
return NULL;
|
||||
return pw->pw_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool create_manifest_file(char const *project_path) {
|
||||
char *name;
|
||||
char cwd[4096];
|
||||
if (strlen(project_path) == 1 && project_path[0] == '.') {
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL) {
|
||||
fputs("Error: Cannot create manifest: Cannot get current working directory.\n", stderr);
|
||||
return false;
|
||||
} else {
|
||||
name = malloc((strlen(cwd)+1)*sizeof(char));
|
||||
strcpy(name, cwd);
|
||||
}
|
||||
} else {
|
||||
name = basename((char *)project_path);
|
||||
}
|
||||
char *uname = get_username();
|
||||
|
||||
FILE *fd = fopen(text_format("%s/" MANIFEST_FNAME, project_path), "w+");
|
||||
if (fd == NULL) {
|
||||
fputs("Error: Cannot create manifest: Cannot open manifest file.\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fd, SAMPLE_MANIFEST, name, uname);
|
||||
|
||||
fclose(fd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void print_help(char **argv) {
|
||||
printf("Usage: %s [command]\n", argv[0]);
|
||||
fputs("\nCommands:\n", stderr);
|
||||
fputs(" * init|i [path=.] - Setup a new project.\n", stderr);
|
||||
fputs(" * build|. - Build project in current working directory.\n", stderr);
|
||||
fputs(" * clean - Clean output code in current working directory.\n", stderr);
|
||||
fputs("\nTo see manifest file usage, check out man tbuild(1)\n", stderr);
|
||||
}
|
||||
|
||||
bool file_exists(char const *path) {
|
||||
struct stat st = {0};
|
||||
return (stat(path, &st) != -1);
|
||||
}
|
||||
|
||||
// FIXME: Implement for Windows.
|
||||
bool makedir(char const *path) {
|
||||
struct stat st = {0};
|
||||
|
||||
if (stat(path, &st) == -1) {
|
||||
mkdir(path, 0700);
|
||||
} else {
|
||||
fprintf(stderr, "Warning: File already exists. Continuing anyway.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool makedir_parenting(char const *path) {
|
||||
char *p;
|
||||
struct stat st = {0};
|
||||
|
||||
for(p=strchr(path+1, '/'); p; p=strchr(p+1, '/')){
|
||||
*p = 0;
|
||||
if(stat(path, &st) == -1 && makedir(path) == true)
|
||||
return true;
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
if(stat(path, &st) == -1)
|
||||
makedir(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void replace_in_file(char const *file, char const *text_to_find, char const *text_to_replace) {
|
||||
FILE *input = fopen(file, "r");
|
||||
FILE *output = fopen("temp.txt", "w");
|
||||
|
||||
char buffer[512];
|
||||
while (fgets(buffer, sizeof(buffer), input) != NULL) {
|
||||
char *pos = strstr(buffer, text_to_find);
|
||||
|
||||
if (pos == NULL) {
|
||||
fputs(buffer, output);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *temp = calloc(strlen(buffer) - strlen(text_to_find) + strlen(text_to_replace) + 1, 1);
|
||||
|
||||
memcpy(temp, buffer, pos - buffer);
|
||||
memcpy(temp + (pos - buffer), text_to_replace, strlen(text_to_replace));
|
||||
memcpy(temp + (pos - buffer) + strlen(text_to_replace),
|
||||
pos + strlen(text_to_find),
|
||||
1 + strlen(buffer) - ((pos - buffer) + strlen(text_to_find)));
|
||||
|
||||
fputs(temp, output);
|
||||
free(temp);
|
||||
}
|
||||
fclose(output);
|
||||
fclose(input);
|
||||
|
||||
rename("temp.txt", file);
|
||||
}
|
||||
|
||||
void convert_to_zealos(char const *path) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
struct stat s;
|
||||
|
||||
if (!(dir = opendir(path)))
|
||||
return;
|
||||
|
||||
if (!(entry = readdir(dir)))
|
||||
return;
|
||||
|
||||
do {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
char fpath[1024];
|
||||
int len = snprintf(fpath, sizeof(fpath)-1, "%s/%s", path, entry->d_name);
|
||||
fpath[len] = 0;
|
||||
|
||||
if (lstat(fpath, &s) == 0 && S_ISDIR(s.st_mode)) { // Is directory?
|
||||
convert_to_zealos(fpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fpath[len-2] != 'H' || fpath[len-3] != '.')
|
||||
continue;
|
||||
|
||||
printf("Converting %s\n", entry->d_name);
|
||||
|
||||
replace_in_file(fpath, "MemCpy", "MemCopy");
|
||||
replace_in_file(fpath, "MemCpy", "MemCopy");
|
||||
replace_in_file(fpath, "MemCmp", "MemCompare");
|
||||
replace_in_file(fpath, "StrCpy", "StrCopy");
|
||||
replace_in_file(fpath, "StrCmp", "StrCompare");
|
||||
replace_in_file(fpath, "StrICmp", "StrICompare");
|
||||
replace_in_file(fpath, "StrNCmp", "StrNCompare");
|
||||
replace_in_file(fpath, "StrNICmp", "StrNICompare");
|
||||
replace_in_file(fpath, "BEqu", "BEqual");
|
||||
replace_in_file(fpath, "LBEqu", "LBEqual");
|
||||
replace_in_file(fpath, "ms", "mouse");
|
||||
replace_in_file(fpath, "Snd", "Sound");
|
||||
replace_in_file(fpath, "SndTaskEndCB", "SoundTaskEndCB");
|
||||
replace_in_file(fpath, "mp_cnt", "mp_count");
|
||||
replace_in_file(fpath, "QueIns", "QueueInsert");
|
||||
replace_in_file(fpath, "QueInit", "QueueInit");
|
||||
replace_in_file(fpath, "QueRem", "QueueRemove");
|
||||
replace_in_file(fpath, "QueDel", "QueueDel");
|
||||
replace_in_file(fpath, "MsSet", "MouseSet");
|
||||
replace_in_file(fpath, "UnusedStk", "UnusedStack");
|
||||
replace_in_file(fpath, "word_lst", "word_list");
|
||||
replace_in_file(fpath, "FileExtRem", "FileExtRemove");
|
||||
replace_in_file(fpath, "cnts", "counts");
|
||||
replace_in_file(fpath, "PostMsg", "MessagePost");
|
||||
replace_in_file(fpath, "PostMsgWait", "MessagePostWait");
|
||||
replace_in_file(fpath, "QSort", "QuickSort");
|
||||
replace_in_file(fpath, "QSortI64", "QuickSortI64");
|
||||
replace_in_file(fpath, "ScanMsg", "MessageScan");
|
||||
replace_in_file(fpath, "cnts", "counts");
|
||||
replace_in_file(fpath, "Dsk", "Disk");
|
||||
replace_in_file(fpath, "collision_cnt", "collision_count");
|
||||
replace_in_file(fpath, "Drv", "Drive");
|
||||
replace_in_file(fpath, "DrvRep", "DriveRep");
|
||||
replace_in_file(fpath, "Drv2Let", "Drive2Letter");
|
||||
replace_in_file(fpath, "LstSub", "ListSub");
|
||||
replace_in_file(fpath, "LstMatch", "ListMatch");
|
||||
replace_in_file(fpath, "DefineLstLoad", "DefineListLoad");
|
||||
replace_in_file(fpath, "ExtDft", "ExtDefault");
|
||||
replace_in_file(fpath, "ExtChg", "ExtChange");
|
||||
replace_in_file(fpath, "RegDft", "RegDefault");
|
||||
replace_in_file(fpath, "\"HC\"", "\"CC\"");
|
||||
replace_in_file(fpath, "CDrv", "CDrive");
|
||||
replace_in_file(fpath, "CDbgInfo", "CDebugInfo");
|
||||
replace_in_file(fpath, "dbg_info", "debug_info");
|
||||
replace_in_file(fpath, "StrFirstRem", "StrFirstRemove");
|
||||
replace_in_file(fpath, "StrLastRem", "StrLastRemove");
|
||||
replace_in_file(fpath, "TempleOS/Apps", "/Apps");
|
||||
replace_in_file(fpath, "adam_task", "sys_task");
|
||||
replace_in_file(fpath, "JobQue", "JobQueue");
|
||||
replace_in_file(fpath, "MSG_", "MESSAGE_");
|
||||
replace_in_file(fpath, ".HC", ".ZC");
|
||||
replace_in_file(fpath, "Msg", "Message");
|
||||
replace_in_file(fpath, "MusicSettingsRst", "MusicSettingsReset");
|
||||
replace_in_file(fpath, "hndlr", "handler");
|
||||
replace_in_file(fpath, "FifoU8Rem", "FifoU8Remove");
|
||||
replace_in_file(fpath, "GodBitsIns", "GodBitsInsert");
|
||||
replace_in_file(fpath, "fp_draw_ms", "fp_draw_mouse");
|
||||
replace_in_file(fpath, "DrawStdMs", "DrawStdMouse");
|
||||
replace_in_file(fpath, "WIG_TASK_DFT", "WIG_TASK_DEFAULT");
|
||||
replace_in_file(fpath, "DirMk", "DirMake");
|
||||
replace_in_file(fpath, "GetI64", "I64Get");
|
||||
replace_in_file(fpath, "GetF64", "F64Get");
|
||||
replace_in_file(fpath, "GetStr", "StrGet");
|
||||
replace_in_file(fpath, "GetChar", "CharGet");
|
||||
|
||||
// Added from Anfintony's Insecticide November 24 2022
|
||||
replace_in_file(fpath, "GetMsg", "MessageGet");
|
||||
replace_in_file(fpath, "DRV_SIGNATURE_VAL", "DRIVE_SIGNATURE_VAL");
|
||||
replace_in_file(fpath, "dv_signature", "drive_signature");
|
||||
replace_in_file(fpath, "DrvTextAttrGet", "DriveTextAttrGet");
|
||||
replace_in_file(fpath, "DrvIsWritable", "DriveIsWritable");
|
||||
replace_in_file(fpath, "gr_palette_std", "gr32_palette_std");
|
||||
replace_in_file(fpath, "GetKey", "KeyGet");
|
||||
replace_in_file(fpath, "STD_DISTRO_DVD_CFG", "STD_DISTRO_DVD_CONFIG");
|
||||
replace_in_file(fpath, "CBGR48", "CBGR24");
|
||||
replace_in_file(fpath, "CFreeLst", "CFreeList");
|
||||
replace_in_file(fpath, "DrvLock", "DriveLock");
|
||||
replace_in_file(fpath, "DrvUnlock", "DriveUnlock");
|
||||
replace_in_file(fpath, "DrvChk", "DriveCheck");
|
||||
replace_in_file(fpath, "AMAlloc", "SysMAlloc");
|
||||
replace_in_file(fpath, "Let2Drv", "Letter2Drive");
|
||||
replace_in_file(fpath, "Let2Let", "Letter2Letter");
|
||||
replace_in_file(fpath, "Let2BlkDev", "Letter2BlkDev");
|
||||
replace_in_file(fpath, "first_drv_let", "first_drive_let");
|
||||
|
||||
// Added by Doodguy and Anfintony November 25 2022
|
||||
replace_in_file(fpath, "ScanKey", "KeyScan");
|
||||
replace_in_file(fpath, "ScanChar", "CharScan");
|
||||
replace_in_file(fpath, "fp_final_scrn_update", "fp_final_screen_update");
|
||||
|
||||
entry->d_name[strlen(entry->d_name)-2] = 'Z';
|
||||
rename(fpath, text_format("%s/%s", path, entry->d_name));
|
||||
|
||||
} while ((entry = readdir(dir)));
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
bool run_scripts(char const *path) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
struct stat s;
|
||||
|
||||
if (!(dir = opendir(path)))
|
||||
return false;
|
||||
|
||||
if (!(entry = readdir(dir)))
|
||||
return false;
|
||||
|
||||
do {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
char fpath[1024];
|
||||
int len = snprintf(fpath, sizeof(fpath)-1, "%s/%s", path, entry->d_name);
|
||||
fpath[len] = 0;
|
||||
|
||||
if (lstat(fpath, &s) == 0 && S_ISDIR(s.st_mode)) { // Is directory?
|
||||
run_scripts(fpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fpath[len-3] != 'p' || fpath[len-2] != 'y' || fpath[len-3] != '.')
|
||||
continue;
|
||||
|
||||
printf("Running %s\n", entry->d_name);
|
||||
char *argv[] = {
|
||||
fpath,
|
||||
NULL
|
||||
};
|
||||
|
||||
execve(python_interpreter_path, argv, NULL);
|
||||
|
||||
} while ((entry = readdir(dir)));
|
||||
closedir(dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
puts("No arguments provided.\n");
|
||||
print_help(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char path_save[PATH_MAX];
|
||||
char abs_exe_path[PATH_MAX];
|
||||
char *p;
|
||||
|
||||
if(!(p = strrchr(argv[0], '/')))
|
||||
getcwd(abs_exe_path, sizeof(abs_exe_path));
|
||||
else {
|
||||
*p = '\0';
|
||||
getcwd(path_save, sizeof(path_save));
|
||||
chdir(argv[0]);
|
||||
getcwd(abs_exe_path, sizeof(abs_exe_path));
|
||||
chdir(path_save);
|
||||
}
|
||||
|
||||
char *project_path = ".";
|
||||
char cmd = tolower(argv[1][0]);
|
||||
if (cmd == 'i') {
|
||||
if (argc > 2) {
|
||||
project_path = calloc(1, (strlen(argv[2])+1)*sizeof(char));
|
||||
strcpy(project_path, argv[2]);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Initializing project in `%s`.\n", project_path);
|
||||
|
||||
bool ret = true;
|
||||
if (!(strlen(project_path) == 1 && project_path[0] == '.'))
|
||||
ret = makedir_parenting(project_path);
|
||||
|
||||
if (!ret) {
|
||||
fputs("Error: Cannot create project: Cannot create directories.\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check if manifest file exists.
|
||||
if (file_exists(text_format("%s/" MANIFEST_FNAME, project_path))) {
|
||||
fputs("Error: Cannot create project: Project already exists!\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
create_manifest_file(project_path);
|
||||
|
||||
if (can_run_command("git"))
|
||||
system(text_format("git init %s", project_path));
|
||||
|
||||
// Free only if alloc'ed, "." doesn't count since it is embedded in the program itself.
|
||||
// Trying to free it if it's "." would cause a crash cause of this.
|
||||
if (argc > 2)
|
||||
free(project_path);
|
||||
} else if (cmd == 'b' || cmd == '.') {
|
||||
struct {
|
||||
bool zeal_build;
|
||||
} options = { 0 };
|
||||
|
||||
for (int i = 2; i < argc; i++) {
|
||||
if (argv[i][0] != '-')
|
||||
continue;
|
||||
|
||||
if (argv[i][1] == '-') {
|
||||
if (strcmp(argv[i], "--zeal"))
|
||||
options.zeal_build = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 1; j < strlen(argv[i]); j++) {
|
||||
switch (argv[i][j]) {
|
||||
case 'z':
|
||||
case 'Z':
|
||||
options.zeal_build = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find project root.
|
||||
char cwd[4096];
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL) {
|
||||
fputs("Error: Cannot build project: Cannot get current working directory.\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
project_path = find_project_root();
|
||||
if (project_path == NULL) {
|
||||
fputs("Error: Cannot build project: Not in a project directory.\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
project_manifest* manifest = load_manifest(text_format("%s/" MANIFEST_FNAME, project_path));
|
||||
puts(buffer_text_format);
|
||||
|
||||
// TODO: Validate dependencies.
|
||||
|
||||
// Create build directory
|
||||
text_format("%s/build", project_path);
|
||||
char *build_dir = malloc((strlen(buffer_text_format)+1)*sizeof(char));
|
||||
strcpy(build_dir, buffer_text_format);
|
||||
text_format("%s/src", project_path);
|
||||
char *src_dir = malloc((strlen(buffer_text_format)+1)*sizeof(char));
|
||||
strcpy(src_dir, buffer_text_format);
|
||||
if (!file_exists(build_dir)) {
|
||||
bool status = makedir(build_dir);
|
||||
if (!status) {
|
||||
fputs("Error: Cannot build project: Cannot create build directory.\n", stderr);
|
||||
free_manifest(manifest);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear and populate.
|
||||
puts("Populating build directory...");
|
||||
clear_directory(build_dir);
|
||||
copy_directory(src_dir, build_dir);
|
||||
if (file_exists(text_format("%s/libs", project_path)))
|
||||
copy_directory(src_dir, buffer_text_format);
|
||||
|
||||
// Run scripts (if any)
|
||||
puts("Running scripts...");
|
||||
// FIXME: This is incredibly hacky.
|
||||
text_format("%s/scripts", project_path);
|
||||
char *scripts_dir = malloc((strlen(buffer_text_format)+1)*sizeof(char));
|
||||
strcpy(scripts_dir, buffer_text_format);
|
||||
if (file_exists(scripts_dir)) {
|
||||
if (!run_scripts(scripts_dir)) {
|
||||
fputs("Failed running script!\b", stderr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.zeal_build) {
|
||||
puts("Converting to ZealOS...");
|
||||
convert_to_zealos(build_dir);
|
||||
}
|
||||
|
||||
// TODO: Obfuscate code if enabled.
|
||||
|
||||
text_format("%s/output", project_path);
|
||||
char *out_dir = malloc((strlen(buffer_text_format)+1)*sizeof(char));
|
||||
strcpy(out_dir, buffer_text_format);
|
||||
if (!file_exists(out_dir)) {
|
||||
bool status = makedir(out_dir);
|
||||
if (!status) {
|
||||
fputs("Error: Cannot build project: Cannot create output directory.\n", stderr);
|
||||
free_manifest(manifest);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.zeal_build)
|
||||
text_format("%s/output/%s-%s.zeal.ISO.C", project_path, manifest->name, manifest->version);
|
||||
else
|
||||
text_format("%s/output/%s-%s.ISO.C", project_path, manifest->name, manifest->version);
|
||||
char *iso_c = malloc((strlen(buffer_text_format)+1)*sizeof(char));
|
||||
strcpy(iso_c, buffer_text_format);
|
||||
#if defined(_WIN32)
|
||||
system(text_format("%s/RedSeaGen.exe '%s' '%s'", abs_exe_path, build_dir, iso_c));
|
||||
#else
|
||||
system(text_format("%s/RedSeaGen '%s' '%s'", abs_exe_path, build_dir, iso_c));
|
||||
#endif
|
||||
|
||||
free(build_dir);
|
||||
free_manifest(manifest);
|
||||
}
|
||||
}
|
||||
|
1
tomlc99
Submodule
1
tomlc99
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 894902820a3ea2f1ec470cd7fe338bde54045cf5
|
Loading…
x
Reference in New Issue
Block a user