refactor: merge io.c file I/O and module resolution functions into vm.c

Remove the separate io.c and io.h source files, inlining their static helper functions (readFile, wrenFilePath, readModule, setRootDirectory) directly into vm.c. This frees io.c as a dedicated built-in module slot and eliminates the cross-file dependency on io.h from main.c, test/api/main.c, and the Xcode/make build systems.
This commit is contained in:
Bob Nystrom
2015-09-14 05:29:47 +00:00
parent 34bcc6bd2d
commit f12581a674
7 changed files with 100 additions and 140 deletions
-101
View File
@@ -1,101 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "io.h"
#include "modules.h"
char const* rootDirectory = NULL;
// Reads the contents of the file at [path] and returns it as a heap allocated
// string.
//
// Returns `NULL` if the path could not be found. Exits if it was found but
// could not be read.
char* readFile(const char* path)
{
FILE* file = fopen(path, "rb");
if (file == NULL) return NULL;
// Find out how big the file is.
fseek(file, 0L, SEEK_END);
size_t fileSize = ftell(file);
rewind(file);
// Allocate a buffer for it.
char* buffer = (char*)malloc(fileSize + 1);
if (buffer == NULL)
{
fprintf(stderr, "Could not read file \"%s\".\n", path);
exit(74);
}
// Read the entire file.
size_t bytesRead = fread(buffer, sizeof(char), fileSize, file);
if (bytesRead < fileSize)
{
fprintf(stderr, "Could not read file \"%s\".\n", path);
exit(74);
}
// Terminate the string.
buffer[bytesRead] = '\0';
fclose(file);
return buffer;
}
void setRootDirectory(const char* path)
{
rootDirectory = path;
}
char* wrenFilePath(const char* name)
{
// The module path is relative to the root directory and with ".wren".
size_t rootLength = rootDirectory == NULL ? 0 : strlen(rootDirectory);
size_t nameLength = strlen(name);
size_t pathLength = rootLength + nameLength + 5;
char* path = (char*)malloc(pathLength + 1);
if (rootDirectory != NULL)
{
memcpy(path, rootDirectory, rootLength);
}
memcpy(path + rootLength, name, nameLength);
memcpy(path + rootLength + nameLength, ".wren", 5);
path[pathLength] = '\0';
return path;
}
char* readModule(WrenVM* vm, const char* module)
{
char* source = readBuiltInModule(module);
if (source != NULL) return source;
// First try to load the module with a ".wren" extension.
char* modulePath = wrenFilePath(module);
char* moduleContents = readFile(modulePath);
free(modulePath);
if (moduleContents != NULL) return moduleContents;
// If no contents could be loaded treat the module name as specifying a
// directory and try to load the "module.wren" file in the directory.
size_t moduleLength = strlen(module);
size_t moduleDirLength = moduleLength + 7;
char* moduleDir = (char*)malloc(moduleDirLength + 1);
memcpy(moduleDir, module, moduleLength);
memcpy(moduleDir + moduleLength, "/module", 7);
moduleDir[moduleDirLength] = '\0';
char* moduleDirPath = wrenFilePath(moduleDir);
free(moduleDir);
moduleContents = readFile(moduleDirPath);
free(moduleDirPath);
return moduleContents;
}
-25
View File
@@ -1,25 +0,0 @@
#ifndef io_h
#define io_h
#include "wren.h"
// Simple IO functions.
// Reads the contents of the file at [path] and returns it as a heap allocated
// string.
//
// Returns `NULL` if the path could not be found. Exits if it was found but
// could not be read.
char* readFile(const char* path);
// Sets the root directory that modules are resolved relative to.
void setRootDirectory(const char* path);
// Attempts to read the source for [module] relative to the current root
// directory.
//
// Returns it if found, or NULL if the module could not be found. Exits if the
// module was found but could not be read.
char* readModule(WrenVM* vm, const char* module);
#endif
-1
View File
@@ -1,7 +1,6 @@
#include <stdio.h>
#include <string.h>
#include "io.h"
#include "vm.h"
#include "wren.h"
+99 -4
View File
@@ -1,7 +1,6 @@
#include <stdio.h>
#include <string.h>
#include "io.h"
#include "modules.h"
#include "vm.h"
#include "scheduler.h"
@@ -9,12 +8,108 @@
#define MAX_LINE_LENGTH 1024 // TODO: Something less arbitrary.
// The single VM instance that the CLI uses.
WrenVM* vm;
static WrenVM* vm;
static WrenBindForeignMethodFn bindMethodFn = NULL;
static WrenBindForeignClassFn bindClassFn = NULL;
uv_loop_t* loop;
static uv_loop_t* loop;
static char const* rootDirectory = NULL;
// Reads the contents of the file at [path] and returns it as a heap allocated
// string.
//
// Returns `NULL` if the path could not be found. Exits if it was found but
// could not be read.
static char* readFile(const char* path)
{
FILE* file = fopen(path, "rb");
if (file == NULL) return NULL;
// Find out how big the file is.
fseek(file, 0L, SEEK_END);
size_t fileSize = ftell(file);
rewind(file);
// Allocate a buffer for it.
char* buffer = (char*)malloc(fileSize + 1);
if (buffer == NULL)
{
fprintf(stderr, "Could not read file \"%s\".\n", path);
exit(74);
}
// Read the entire file.
size_t bytesRead = fread(buffer, sizeof(char), fileSize, file);
if (bytesRead < fileSize)
{
fprintf(stderr, "Could not read file \"%s\".\n", path);
exit(74);
}
// Terminate the string.
buffer[bytesRead] = '\0';
fclose(file);
return buffer;
}
// Converts the module [name] to a file path.
static char* wrenFilePath(const char* name)
{
// The module path is relative to the root directory and with ".wren".
size_t rootLength = rootDirectory == NULL ? 0 : strlen(rootDirectory);
size_t nameLength = strlen(name);
size_t pathLength = rootLength + nameLength + 5;
char* path = (char*)malloc(pathLength + 1);
if (rootDirectory != NULL)
{
memcpy(path, rootDirectory, rootLength);
}
memcpy(path + rootLength, name, nameLength);
memcpy(path + rootLength + nameLength, ".wren", 5);
path[pathLength] = '\0';
return path;
}
// Attempts to read the source for [module] relative to the current root
// directory.
//
// Returns it if found, or NULL if the module could not be found. Exits if the
// module was found but could not be read.
static char* readModule(WrenVM* vm, const char* module)
{
char* source = readBuiltInModule(module);
if (source != NULL) return source;
// First try to load the module with a ".wren" extension.
char* modulePath = wrenFilePath(module);
char* moduleContents = readFile(modulePath);
free(modulePath);
if (moduleContents != NULL) return moduleContents;
// If no contents could be loaded treat the module name as specifying a
// directory and try to load the "module.wren" file in the directory.
size_t moduleLength = strlen(module);
size_t moduleDirLength = moduleLength + 7;
char* moduleDir = (char*)malloc(moduleDirLength + 1);
memcpy(moduleDir, module, moduleLength);
memcpy(moduleDir + moduleLength, "/module", 7);
moduleDir[moduleDirLength] = '\0';
char* moduleDirPath = wrenFilePath(moduleDir);
free(moduleDir);
moduleContents = readFile(moduleDirPath);
free(moduleDirPath);
return moduleContents;
}
// Binds foreign methods declared in either built in modules, or the injected
// API test modules.
@@ -89,7 +184,7 @@ void runFile(const char* path)
root = (char*)malloc(lastSlash - path + 2);
memcpy(root, path, lastSlash - path + 1);
root[lastSlash - path + 1] = '\0';
setRootDirectory(root);
rootDirectory = root;
}
char* source = readFile(path);