ast_t* package_load(ast_t* from, const char* path, pass_opt_t* options) { const char* magic = find_magic_package(path); const char* name = path; if(magic == NULL) { // Lookup (and hence normalise) path name = find_path(from, path); if(name == NULL) return NULL; } ast_t* program = ast_nearest(from, TK_PROGRAM); ast_t* package = ast_get(program, name, NULL); if(package != NULL) // Package already loaded return package; package = create_package(program, name); if(report_build) printf("Building %s\n", path); if(magic != NULL) { if(!parse_source_code(package, magic, options)) return NULL; } else { if(!parse_files_in_dir(package, name, options)) return NULL; } if(ast_child(package) == NULL) { ast_error(package, "no source files in package '%s'", path); return NULL; } if(!package_passes(package, options)) return NULL; return package; }
ast_t* package_load(ast_t* from, const char* path, pass_opt_t* options) { assert(from != NULL); const char* magic = find_magic_package(path); const char* full_path = path; const char* qualified_name = path; ast_t* program = ast_nearest(from, TK_PROGRAM); if(magic == NULL) { // Lookup (and hence normalise) path bool is_relative = false; full_path = find_path(from, path, &is_relative); if(full_path == NULL) return NULL; if((from != program) && is_relative) { // Package to load is relative to from, build the qualified name // The qualified name should be relative to the program being built package_t* from_pkg = (package_t*)ast_data(ast_child(program)); if(from_pkg != NULL) { const char* base_name = from_pkg->qualified_name; size_t base_name_len = strlen(base_name); size_t path_len = strlen(path); size_t len = base_name_len + path_len + 2; char* q_name = (char*)pool_alloc_size(len); memcpy(q_name, base_name, base_name_len); q_name[base_name_len] = '/'; memcpy(q_name + base_name_len + 1, path, path_len); q_name[len - 1] = '\0'; qualified_name = stringtab_consume(q_name, len); } } } ast_t* package = ast_get(program, full_path, NULL); // Package already loaded if(package != NULL) return package; package = create_package(program, full_path, qualified_name); if(report_build) printf("Building %s -> %s\n", path, full_path); if(magic != NULL) { if(!parse_source_code(package, magic, options)) return NULL; } else { if(!parse_files_in_dir(package, full_path, options)) return NULL; } if(ast_child(package) == NULL) { ast_error(package, "no source files in package '%s'", path); return NULL; } if(!ast_passes_subtree(&package, options, options->program_pass)) { // If these passes failed, don't run future passes. ast_setflag(package, AST_FLAG_PRESERVE); return NULL; } return package; }
ast_t* package_load(ast_t* from, const char* path, pass_opt_t* options) { const char* magic = find_magic_package(path); const char* full_path = path; const char* qualified_name = path; ast_t* program = ast_nearest(from, TK_PROGRAM); if(magic == NULL) { // Lookup (and hence normalise) path bool is_relative = false; full_path = find_path(from, path, &is_relative); if(full_path == NULL) return NULL; if((from != NULL) && is_relative) { // Package to load is relative to from, build the qualified name // The qualified name should be relative to the program being built package_t* from_pkg = (package_t*)ast_data(ast_child(program)); if(from_pkg != NULL) { const char* base_name = from_pkg->qualified_name; size_t base_name_len = strlen(base_name); size_t path_len = strlen(path); size_t len = base_name_len + path_len + 2; char* q_name = (char*)pool_alloc_size(len); memcpy(q_name, base_name, base_name_len); q_name[base_name_len] = '/'; memcpy(q_name + base_name_len + 1, path, path_len); q_name[len - 1] = '\0'; qualified_name = stringtab_consume(q_name, len); } } } ast_t* package = ast_get(program, full_path, NULL); // Package already loaded if(package != NULL) return package; package = create_package(program, full_path, qualified_name); if(report_build) printf("Building %s -> %s\n", path, full_path); if(magic != NULL) { if(!parse_source_code(package, magic, options)) return NULL; } else { if(!parse_files_in_dir(package, full_path, options)) return NULL; } if(ast_child(package) == NULL) { ast_error(package, "no source files in package '%s'", path); return NULL; } // We add new packages to the end of the program, so they will be reached by // the current pass processing. This means we need to catch up the new // package to the previous pass if(!ast_passes_subtree(&package, options, pass_prev(options->type_catchup_pass))) return NULL; return package; }
ast_t* package_load(ast_t* from, const char* path, pass_opt_t* opt) { pony_assert(from != NULL); magic_package_t* magic = find_magic_package(path, opt); const char* full_path = path; const char* qualified_name = path; ast_t* program = ast_nearest(from, TK_PROGRAM); if(magic == NULL) { // Lookup (and hence normalise) path bool is_relative = false; bool found_notdir = false; full_path = find_path(from, path, &is_relative, &found_notdir, opt); if(full_path == NULL) { errorf(opt->check.errors, path, "couldn't locate this path"); if(found_notdir) errorf_continue(opt->check.errors, path, "note that a compiler " "invocation or a 'use' directive must refer to a directory"); return NULL; } if((from != program) && is_relative) { // Package to load is relative to from, build the qualified name // The qualified name should be relative to the program being built package_t* from_pkg = (package_t*)ast_data(ast_child(program)); if(from_pkg != NULL) { const char* base_name = from_pkg->qualified_name; size_t base_name_len = strlen(base_name); size_t path_len = strlen(path); size_t len = base_name_len + path_len + 2; char* q_name = (char*)ponyint_pool_alloc_size(len); memcpy(q_name, base_name, base_name_len); q_name[base_name_len] = '/'; memcpy(q_name + base_name_len + 1, path, path_len); q_name[len - 1] = '\0'; qualified_name = stringtab_consume(q_name, len); } } // we are loading the package specified as program dir if(from == program) { // construct the qualified name from the basename of the full path const char* basepath = strrchr(full_path, '/'); if(basepath == NULL) { basepath = full_path; } else { basepath = basepath + 1; } qualified_name = basepath; } } ast_t* package = ast_get(program, full_path, NULL); // Package already loaded if(package != NULL) return package; package = create_package(program, full_path, qualified_name, opt); if(opt->verbosity >= VERBOSITY_INFO) fprintf(stderr, "Building %s -> %s\n", path, full_path); if(magic != NULL) { if(magic->src != NULL) { if(!parse_source_code(package, magic->src, opt)) return NULL; } else if(magic->mapped_path != NULL) { if(!parse_files_in_dir(package, magic->mapped_path, opt)) return NULL; } else { return NULL; } } else { if(!parse_files_in_dir(package, full_path, opt)) return NULL; } if(ast_child(package) == NULL) { ast_error(opt->check.errors, package, "no source files in package '%s'", path); return NULL; } if(!ast_passes_subtree(&package, opt, opt->program_pass)) { // If these passes failed, don't run future passes. ast_setflag(package, AST_FLAG_PRESERVE); return NULL; } return package; }