示例#1
0
const char *vfs_basename( const char *path )
{
    const char *basename;

    // deduce basename (incl. extension) for length check
    if (basename = c_strrchr( path, '/' )) {
        basename++;
    } else if (basename = c_strrchr( path, ':' )) {
        basename++;
    } else {
        basename = path;
    }

    return basename;
}
示例#2
0
void fxLoadModule(txMachine* the, txID moduleID)
{
	txArchive* archive = the->archive;
	txSlot* key = fxGetKey(the, moduleID);
 	char buffer[PATH_MAX];
	txString path = buffer;
	txString dot;
	txString* extension;
	txLoader* loader;
 	c_strcpy(path, key->value.key.string);
	if (archive) {
		if (!c_strncmp(path, archive->base, archive->baseLength)) {
			txInteger c = archive->scriptCount, i;
			txScript* script = archive->scripts;
			path += archive->baseLength;
			for (i = 0; i < c; i++) {
				if (!c_strcmp(path, script->path)) {
					fxResolveModule(the, moduleID, script, fxLoadLibrary(the, key->value.key.string, C_NULL), fxUnloadLibrary);
					return;
				}
				script++;
			}
		}
	}
	dot = c_strrchr(path, '.');
	for (extension = gxExtensions, loader = gxLoaders; *extension; extension++, loader++) {
		if (!c_strcmp(dot, *extension)) {
			(**loader)(the, buffer, moduleID);
			return;
		}
	}
}
示例#3
0
txModuleData* fxLoadLibrary(txMachine* the, txString path, txScript* script)
{
	txModuleData* data = C_NULL;
	if (script) {
		if (script->version[3] == 1) {
			char buffer[PATH_MAX];
			char* dot;
			void* library;
			txCallback callback;
			c_strcpy(buffer, path);
			dot = c_strrchr(buffer, '.');
			if (dot)
				*dot = 0;
			#if mxWindows
				c_strcat(buffer, ".dll");
				#if mxReport
					fxReport(the, "# Loading library \"%s\"\n", buffer);
				#endif
				library = LoadLibrary(buffer);
				mxElseError(library);
				callback = (txCallback)GetProcAddress(library, "xsHostModule");
				mxElseError(callback);
			#else
				c_strcat(buffer, ".so");
				#if mxReport
					fxReport(the, "# Loading library \"%s\"\n", buffer);
				#endif
				library = dlopen(buffer, RTLD_NOW);
				mxElseError(library);
				callback = (txCallback)dlsym(library, "xsHostModule");
				mxElseError(callback);
			#endif
			data = c_malloc(sizeof(txModuleData) + c_strlen(buffer));
			mxElseError(data);
			data->library = library;
			data->the = the;
			c_strcpy(data->path, buffer);
			script->callback = callback;
			return data;
		}
	}
#if mxReport
	data = c_malloc(sizeof(txModuleData) + c_strlen(path));
	mxElseError(data);
	data->library = C_NULL;
	data->the = the;
	c_strcpy(data->path, path);
	fxReport(the, "# Loading module \"%s\"\n", path);
#endif
	return data;
}
示例#4
0
void* fxMapArchive(txString base, txCallbackAt callbackAt)
{
	int error = 0;
	txArchive* archive = C_NULL;
#if mxWindows
#else
	struct stat statbuf;
#endif
	txString p;
	Atom atom;
	int c, i;
	txString* symbol;
	txScript* script;

	archive = c_malloc(sizeof(txArchive));
	bailElse(archive);
	c_memset(archive, 0, sizeof(txArchive));
	c_strcpy(archive->base, base);
#if mxWindows
	archive->file = CreateFile(base, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	bailElse(archive->file != INVALID_HANDLE_VALUE);
	archive->size = GetFileSize(archive->file, &archive->size);
	bailElse(archive->size != INVALID_FILE_SIZE);
	archive->mapping = CreateFileMapping(archive->file, NULL, PAGE_READONLY, 0, (SIZE_T)archive->size, NULL);
	bailElse(archive->mapping != INVALID_HANDLE_VALUE);
	archive->address = MapViewOfFile(archive->mapping, FILE_MAP_READ, 0, 0, (SIZE_T)archive->size);
	bailElse(archive->address != NULL);
#else
	archive->fd = open(base, O_RDONLY);
	bailElse(archive->fd >= 0);
	fstat(archive->fd, &statbuf);
	archive->size = statbuf.st_size;
	archive->address = mmap(NULL, archive->size, PROT_READ, MAP_SHARED, archive->fd, 0);
	bailElse(archive->address != MAP_FAILED);
#endif
	p = archive->address;
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_ARCHIVE);
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_VERSION);
	bailAssert(*p++ == XS_MAJOR_VERSION);
	bailAssert(*p++ == XS_MINOR_VERSION);
	bailAssert(*p++ == XS_PATCH_VERSION);
	if ((*p++) && !callbackAt) {
		char* dot;
		dot = c_strrchr(archive->base, '.');
		if (dot)
			*dot = 0;
		#if mxWindows
			c_strcat(archive->base, ".dll");
			archive->library = LoadLibrary(archive->base);
			bailElse(archive->library);
			callbackAt = (txCallbackAt)GetProcAddress(archive->library, "xsHostModuleAt");
			bailElse(callbackAt);
		#else
			c_strcat(archive->base, ".so");
			archive->library = dlopen(archive->base, RTLD_NOW);
			if (!archive->library)
        		fprintf(stderr, "%s\n", dlerror());
			bailElse(archive->library);
			callbackAt = (txCallbackAt)dlsym(archive->library, "xsHostModuleAt");
			bailElse(callbackAt);
		#endif
		archive->keys = callbackAt(0);
	}
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_SYMBOLS);
	c = archive->symbolCount = ntohs(*((unsigned short*)p));
	p += 2;
	if (c) {
		symbol = archive->symbols = c_malloc(c * sizeof(txString));
		for (i = 0; i < c; i++) {
			*symbol = p;
			p += c_strlen(p) + 1;
			symbol++;
		}
	}
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_PATHS);
	c = archive->scriptCount = ntohs(*((unsigned short*)p));
	p += 2;
	script = archive->scripts = c_malloc(c * sizeof(txScript));
	c_memset(script, 0, c * sizeof(txScript));
	for (i = 1; i <= c; i++) {
		if (callbackAt)
			script->callback = callbackAt(i);
		script->path = p;
		p += c_strlen(p) + 1;
		script++;
	}
	
	script = archive->scripts;
	for (i = 0; i < c; i++) {
		p = fxMapAtom(p, &atom);
		bailAssert(atom.atomType == XS_ATOM_CODE);
		script->codeSize = atom.atomSize - sizeof(atom);
		script->codeBuffer = (txS1*)p;
		p += script->codeSize;
		script++;
	}
	
	p = c_strrchr(archive->base, mxSeparator);
	if (p) {
		p++;
		*p = 0;
		archive->baseLength = p - archive->base;
	}
bail:
	if (error) {
		fxUnmapArchive(archive);
		archive = C_NULL;
	}
	return archive;
}
示例#5
0
txID fxFindModule(txMachine* the, txID moduleID, txSlot* slot)
{
	char name[PATH_MAX];
	char base[PATH_MAX];
	txBoolean absolute, relative, search;
	txSlot *key, *iterator, *result;
	txString dot, slash;
	txID id;
	
	fxToStringBuffer(the, slot, name, sizeof(name));
	if ((!c_strncmp(name, "./", 2)) || (!c_strncmp(name, "../", 3))) {
		absolute = 0;
		relative = (moduleID == XS_NO_ID) ? 0 : 1;
		search = 0;
	}
	else if ((!c_strncmp(name, "/", 1))) {
		absolute = 1;
		relative = 0;
		search = 0;
	}
	else {
		absolute = 0;
		relative = (moduleID == XS_NO_ID) ? 0 : 1;
		search = 1;
	}
	slash = c_strrchr(name, '/');
	if (!slash)
		slash = name;
	dot = c_strrchr(slash, '.');
	if (!dot)
		dot = name + c_strlen(name);
	
	if (absolute) {
		if (fxFindURI(the, "", name, dot, &id))
			return id;
	}
	if (relative) {
		key = fxGetKey(the, moduleID);
  		c_strcpy(base, key->value.key.string);
		if (fxFindURI(the, base, name, dot, &id))
			return id;
	}
	if (search) {
		mxCallID(&mxModulePaths, mxID(_Symbol_iterator), 0);
		iterator = the->stack;
		for (;;) {
			mxCallID(iterator, mxID(_next), 0);
			result = the->stack;
			mxGetID(result, mxID(_done));
			if (fxToBoolean(the, the->stack))
				break;
			the->stack++;
			mxGetID(result, mxID(_value));
			fxToStringBuffer(the, the->stack++, base, sizeof(base));
			if (fxFindURI(the, base, name, dot, &id))
				return id;
		}
	}
	mxReferenceError("module \"%s\" not found", name);
	return XS_NO_ID;
}
示例#6
0
void* fxMapArchive(txString base, txCallbackAt callbackAt)
{
	FskErr err = kFskErrNone;
	txArchive* archive = NULL;
	txString p;
	Atom atom;
	int c, i;
	txString* symbol;
	txScript* script;

	bailIfError(FskMemPtrNewClear(sizeof(txArchive), &archive));
	c_strcpy(archive->base, base);
	bailIfError(FskFileMap(base, (unsigned char**)&(archive->address), &(archive->size), 0, &(archive->map)));

	p = archive->address;
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_ARCHIVE);
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_VERSION);
	bailAssert(*p++ == XS_MAJOR_VERSION);
	bailAssert(*p++ == XS_MINOR_VERSION);
	bailAssert(*p++ == XS_PATCH_VERSION);
	if ((*p++) && !callbackAt) {
		char* dot;
		dot = c_strrchr(archive->base, '.');
		if (dot)
			*dot = 0;
		#if mxWindows
			c_strcat(archive->base, ".dll");
		#else
			c_strcat(archive->base, ".so");
		#endif
		bailIfError(FskLibraryLoad(&(archive->library), archive->base));
		bailIfError(FskLibraryGetSymbolAddress(archive->library, "xsHostModuleAt", &callbackAt));
		archive->keys = callbackAt(0);
	}

	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_SYMBOLS);
	mxDecode2(p, archive->symbolCount);
	c = archive->symbolCount;
	if (c) {
		bailIfError(FskMemPtrNew(c * sizeof(txString), &(archive->symbols)));
		symbol = archive->symbols;
		for (i = 0; i < c; i++) {
			*symbol = p;
			p += c_strlen(p) + 1;
			symbol++;
		}
	}

	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_PATHS);
	mxDecode2(p, archive->scriptCount);
	c = archive->scriptCount;
	bailIfError(FskMemPtrNewClear(c * sizeof(txScript), &(archive->scripts)));
	script = archive->scripts;
	for (i = 1; i <= c; i++) {
		if (callbackAt)
			script->callback = callbackAt(i);
		script->path = p;
		bailIfNULL(script->path);
		p += c_strlen(p) + 1;
		script++;
	}
	
	script = archive->scripts;
	for (i = 0; i < c; i++) {
		p = fxMapAtom(p, &atom);
		bailAssert(atom.atomType == XS_ATOM_CODE);
		script->codeSize = atom.atomSize - sizeof(atom);
		script->codeBuffer = (txS1*)p;
		p += script->codeSize;
		script++;
	}
	
	p = c_strrchr(archive->base, '/');
	if (p) {
		p++;
		*p = 0;
		archive->baseLength = p - archive->base;
	}
bail:
	if (err) {
		fxUnmapArchive(archive);
		archive = NULL;
	}
	return archive;
}