static void find_arch(ident_t name, int kind, void *context) { lib_search_params_t *params = context; ident_t prefix = ident_until(name, '-'); if ((kind == T_ARCH) && (prefix == params->name)) { tree_t t = lib_get_check_stale(params->lib, name); assert(t != NULL); if (*(params->tree) == NULL) *(params->tree) = t; else { lib_mtime_t old_mtime = lib_mtime(params->lib, tree_ident(*(params->tree))); lib_mtime_t new_mtime = lib_mtime(params->lib, tree_ident(t)); if (new_mtime == old_mtime) { // Analysed at the same time: compare line number // Note this assumes both architectures are from the same // file but this shouldn't be a problem with high-resolution // timestamps uint16_t new_line = tree_loc(t)->first_line; uint16_t old_line = tree_loc(*(params->tree))->first_line; if (new_line > old_line) *(params->tree) = t; } else if (new_mtime > old_mtime) *(params->tree) = t; } } }
static void elab_add_context(tree_t t, const elab_ctx_t *ctx) { ident_t cname = tree_ident(t); ident_t lname = ident_until(cname, '.'); lib_t lib = elab_find_lib(lname, ctx); tree_t unit = lib_get(lib, cname); if (unit == NULL) fatal_at(tree_loc(t), "cannot find unit %s", istr(cname)); else if (tree_kind(unit) == T_PACKAGE) { elab_copy_context(unit, ctx); ident_t name = tree_ident(unit); ident_t body_i = ident_prefix(name, ident_new("body"), '-'); tree_t body = lib_get(lib, body_i); if (body != NULL) elab_copy_context(unit, ctx); } // Always use real library name rather than WORK alias tree_set_ident(t, tree_ident(unit)); tree_add_context(ctx->out, t); }
static lib_t elab_find_lib(ident_t name, const elab_ctx_t *ctx) { lib_t tmp = lib_work(); lib_set_work(ctx->library); lib_t lib = lib_find(ident_until(name, '.'), true); lib_set_work(tmp); return lib; }
END_TEST START_TEST(test_until) { ident_t i; i = ident_new("aye.bee.c"); fail_unless(ident_until(i, '.') == ident_new("aye")); }
static lib_t elab_find_lib(ident_t name, const elab_ctx_t *ctx) { lib_t tmp = lib_work(); lib_set_work(ctx->library); lib_t lib = lib_find(istr(ident_until(name, '.')), true, true); if (lib == NULL) fatal("cannot continue"); lib_set_work(tmp); return lib; }
static void elab_use_clause(tree_t use, const elab_ctx_t *ctx) { tree_set_ident2(use, all_i); ident_t name = tree_ident(use); ident_t lname = ident_until(name, '.'); elab_ctx_t new_ctx = *ctx; new_ctx.library = elab_find_lib(lname, ctx); if (name == lname) lib_walk_index(new_ctx.library, elab_context_walk_fn, &new_ctx); else if (!elab_have_context(ctx->out, name)) elab_add_context(use, &new_ctx); }
static void link_context(tree_t ctx, FILE *deps, context_fn_t fn) { ident_t cname = tree_ident(ctx); ident_t lname = ident_until(cname, '.'); lib_t lib = lib_find(istr(lname), true, true); if (lib == NULL) fatal("cannot link library %s", istr(lname)); if (lname == cname) { lib_walk_params_t params = { .lib = lib, .deps = deps, .fn = fn }; lib_walk_index(lib, link_walk_lib, ¶ms); }
static void elab_copy_context(tree_t src, const elab_ctx_t *ctx) { const int nsrc = tree_contexts(src); for (int i = 0; i < nsrc; i++) { tree_t c = tree_context(src, i); if (tree_kind(c) != T_USE) continue; tree_set_ident2(c, all_i); ident_t name = tree_ident(c); ident_t lname = ident_until(name, '.'); elab_ctx_t new_ctx = *ctx; new_ctx.library = elab_find_lib(lname, ctx); if (name == lname) lib_walk_index(new_ctx.library, elab_context_walk_fn, &new_ctx); else if (!elab_have_context(ctx->out, name)) elab_add_context(c, &new_ctx); } }