4c0f559d23
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@15 260f80e4-7a28-3924-810f-c04153c831b5
159 lines
5.0 KiB
C++
159 lines
5.0 KiB
C++
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// Handle dart scripts.
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include "include/dart_api.h"
|
|
|
|
#include "bin/builtin.h"
|
|
#include "bin/file.h"
|
|
#include "bin/globals.h"
|
|
#include "bin/process_script.h"
|
|
|
|
static const char* CanonicalizeUrl(const char* reference_dir,
|
|
const char* filename) {
|
|
static const char* kDartScheme = "dart:";
|
|
static const intptr_t kDartSchemeLen = strlen(kDartScheme);
|
|
// If the URL starts with "dart:" then it is not modified as it will be
|
|
// handled by the VM internally.
|
|
if (strncmp(filename, kDartScheme, kDartSchemeLen) == 0) {
|
|
return strdup(filename);
|
|
}
|
|
|
|
if (File::IsAbsolutePath(filename)) {
|
|
return strdup(filename);
|
|
}
|
|
|
|
char* path = strdup(reference_dir);
|
|
if (path == NULL) {
|
|
return NULL;
|
|
}
|
|
char* path_sep = strrchr(path, File::PathSeparator()[0]);
|
|
if (path_sep == NULL) {
|
|
// No separator found: Reference is a file in local directory.
|
|
return strdup(filename);
|
|
}
|
|
*path_sep = '\0';
|
|
intptr_t len = snprintf(NULL, 0, "%s%s%s",
|
|
path, File::PathSeparator(), filename);
|
|
char* absolute_filename = reinterpret_cast<char*>(malloc(len + 1));
|
|
ASSERT(absolute_filename != NULL);
|
|
|
|
snprintf(absolute_filename, len + 1, "%s%s%s",
|
|
path, File::PathSeparator(), filename);
|
|
|
|
free(path);
|
|
return absolute_filename;
|
|
}
|
|
|
|
|
|
static Dart_Result ReadStringFromFile(const char* filename) {
|
|
File* file = File::OpenFile(filename, false);
|
|
if (file == NULL) {
|
|
const char* format = "Unable to open file: %s";
|
|
intptr_t len = snprintf(NULL, 0, format, filename);
|
|
// TODO(iposva): Allocate from the zone instead of leaking error string
|
|
// here. On the other hand the binary is about the exit anyway.
|
|
char* error_msg = reinterpret_cast<char*>(malloc(len + 1));
|
|
snprintf(error_msg, len + 1, format, filename);
|
|
return Dart_ErrorResult(error_msg);
|
|
}
|
|
intptr_t len = file->Length();
|
|
char* text_buffer = reinterpret_cast<char*>(malloc(len + 1));
|
|
if (text_buffer == NULL) {
|
|
delete file;
|
|
return Dart_ErrorResult("Unable to allocate buffer");
|
|
}
|
|
if (!file->ReadFully(text_buffer, len)) {
|
|
delete file;
|
|
return Dart_ErrorResult("Unable to fully read contents");
|
|
}
|
|
text_buffer[len] = '\0';
|
|
delete file;
|
|
Dart_Handle str = Dart_NewString(text_buffer);
|
|
free(text_buffer);
|
|
return Dart_ResultAsObject(str);
|
|
}
|
|
|
|
|
|
static Dart_Result LibraryTagHandler(Dart_LibraryTag tag,
|
|
Dart_Handle library,
|
|
Dart_Handle url) {
|
|
if (!Dart_IsLibrary(library)) {
|
|
return Dart_ErrorResult("not a library");
|
|
}
|
|
if (!Dart_IsString8(url)) {
|
|
return Dart_ErrorResult("url is not a string");
|
|
}
|
|
Dart_Result result = Dart_StringToCString(url);
|
|
if (!Dart_IsValidResult(result)) {
|
|
return Dart_ErrorResult("accessing url characters failed");
|
|
}
|
|
const char* url_chars = Dart_GetResultAsCString(result);
|
|
|
|
if (tag == kCanonicalizeUrl) {
|
|
// Create the full path based on the including library and the current url.
|
|
|
|
// Get the url of the calling library.
|
|
result = Dart_LibraryUrl(library);
|
|
if (!Dart_IsValidResult(result)) {
|
|
return Dart_ErrorResult("accessing library url failed");
|
|
}
|
|
Dart_Handle library_url = Dart_GetResult(result);
|
|
if (!Dart_IsString8(library_url)) {
|
|
return Dart_ErrorResult("library url is not a string");
|
|
}
|
|
result = Dart_StringToCString(library_url);
|
|
if (!Dart_IsValidResult(result)) {
|
|
return Dart_ErrorResult("accessing library url characters failed");
|
|
}
|
|
const char* library_url_chars = Dart_GetResultAsCString(result);
|
|
|
|
// Calculate the path.
|
|
const char* canon_url_chars = CanonicalizeUrl(library_url_chars, url_chars);
|
|
Dart_Handle canon_url = Dart_NewString(canon_url_chars);
|
|
free(const_cast<char*>(canon_url_chars));
|
|
|
|
return Dart_ResultAsObject(canon_url);
|
|
}
|
|
|
|
// The tag is either an import or a source tag. Read the file based on the
|
|
// url chars.
|
|
result = ReadStringFromFile(url_chars);
|
|
if (!Dart_IsValidResult(result)) {
|
|
return result;
|
|
}
|
|
Dart_Handle source = Dart_GetResult(result);
|
|
|
|
if (tag == kImportTag) {
|
|
result = Dart_LoadLibrary(url, source);
|
|
if (Dart_IsValidResult(result)) {
|
|
// TODO(iposva): Should the builtin library be added to all libraries?
|
|
Dart_Handle new_lib = Dart_GetResult(result);
|
|
Builtin_ImportLibrary(new_lib);
|
|
}
|
|
return result;
|
|
} else if (tag == kSourceTag) {
|
|
return Dart_LoadSource(library, url, source);
|
|
}
|
|
return Dart_ErrorResult("wrong tag");
|
|
}
|
|
|
|
|
|
Dart_Result LoadScript(const char* script_name) {
|
|
Dart_Result result = ReadStringFromFile(script_name);
|
|
if (!Dart_IsValidResult(result)) {
|
|
return result;
|
|
}
|
|
Dart_Handle source = Dart_GetResult(result);
|
|
Dart_Handle url = Dart_NewString(script_name);
|
|
|
|
return Dart_LoadScript(url, source, LibraryTagHandler);
|
|
}
|