// 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 #include #include #include #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(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(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(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(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); }