static void *worker(void *data) { worker_t *w = (worker_t *)data; for(size_t i = w->start; i < w->n; i+= w->step) { kseq_t *s = &kv_A(w->reads, i); aln_v result = align_read(s, w->ref_seqs, w->config); kstring_t str = { 0, 0, NULL }; write_sam_records(&str, s, result, w->ref_seqs, w->read_group_id, w->config->n_keep, w->config->max_drop); w->sams[i] = str; for(size_t j = 0; j < kv_size(result); j++) free(kv_A(result, j).cigar); kv_destroy(result); kseq_stack_destroy(s); } return 0; }
// reproject shape shape_t* shape_proj( const shape_t* shape, const char* from, const char* to ){ shape_t* projected = shape_copy(shape); projPJ old_prj = pj_init_plus(from); projPJ new_prj = pj_init_plus(to); for(uint32_t i=0; i<kv_size(projected->points); i++) { point_t* p = &kv_A(projected->points, i); p->x *= DEG_TO_RAD; p->y *= DEG_TO_RAD; int32_t err = pj_transform(old_prj, new_prj, 1, 0, &p->x, &p->y, NULL); if (err) fprintf(stderr, "ERR%d %s\n", err, pj_strerrno(err)); assert(err == 0); } for(uint32_t i=0; i<kv_size(projected->hull); i++) { point_t* p = &kv_A(projected->hull, i); p->x *= DEG_TO_RAD; p->y *= DEG_TO_RAD; int32_t err = pj_transform(old_prj, new_prj, 1, 0, &p->x, &p->y, NULL); if (err) fprintf(stderr, "ERR%d %s\n", err, pj_strerrno(err)); assert(err == 0); } pj_free(old_prj); pj_free(new_prj); return projected; }
void mesh_draw(cairo_t* ctx, mesh_t* m) { for(uint32_t tid=0; tid<kv_size(m->triangles); tid++){ triangle_t t = kv_A(m->triangles, tid); point_t p1 = kv_A(m->points, t.a); point_t p2 = kv_A(m->points, t.b); point_t p3 = kv_A(m->points, t.c); cairo_move_to(ctx, p1.x, p1.y); cairo_line_to(ctx, p2.x, p2.y); cairo_line_to(ctx, p3.x, p3.y); cairo_line_to(ctx, p1.x, p1.y); double r = rand()%100/100.0; double g = rand()%100/100.0; double b = rand()%100/100.0; cairo_set_source_rgb(ctx, r, g, b); cairo_fill_preserve(ctx); cairo_set_line_width(ctx, 1.0); cairo_set_source_rgb(ctx, 1.0, 1.0, 1.0); cairo_stroke(ctx); } }
static void write_sam_records(kstring_t *str, const kseq_t *read, const aln_v result, const kseq_v ref_seqs, const char *read_group_id, const int32_t n_keep, const int32_t max_drop) { if(kv_size(result) == 0) return; const int32_t min_score = kv_A(result, 0).loc.score - max_drop; /* Alignments are sorted by decreasing score */ for(size_t i = 0; i < kv_size(result) && (n_keep <= 0 || i < n_keep); i++) { aln_t a = kv_A(result, i); if(a.loc.score < min_score) break; ksprintf(str, "%s\t%d\t", read->name.s, i == 0 ? 0 : 256); // Secondary ksprintf(str, "%s\t%d\t%d\t", kv_A(ref_seqs, a.target_idx).name.s, /* Reference */ a.loc.tb + 1, /* POS */ 40); /* MAPQ */ if(a.loc.qb) ksprintf(str, "%dS", a.loc.qb); for(size_t c = 0; c < a.n_cigar; c++) { int32_t letter = 0xf&*(a.cigar + c); int32_t length = (0xfffffff0&*(a.cigar + c))>>4; ksprintf(str, "%d", length); if(letter == 0) ksprintf(str, "M"); else if(letter == 1) ksprintf(str, "I"); else ksprintf(str, "D"); } if(a.loc.qe + 1 != read->seq.l) ksprintf(str, "%luS", read->seq.l - a.loc.qe - 1); ksprintf(str, "\t*\t0\t0\t"); ksprintf(str, "%s\t", i > 0 ? "*" : read->seq.s); if(read->qual.s && i == 0) ksprintf(str, "%s", read->qual.s); else ksprintf(str, "*"); ksprintf(str, "\tAS:i:%d\tNM:i:%d", a.loc.score, a.nm); if(read_group_id) ksprintf(str, "\tRG:Z:%s", read_group_id); kputs("\n", str); } }
int undigify2(vec_u8_t v2, vec_u8_t v1) { int ret = 0; int shift = 1; for(size_t i = 0 ; i < kv_size(v1) ; i++) { ret += kv_A(v1, i) * shift; shift *= 10; } for(size_t i = 0 ; i < kv_size(v2) ; i++) { ret += kv_A(v2, i) * shift; shift *= 10; } return ret; }
/* Returns total size after dropping low scores */ void drop_low_scores(aln_v *vec, int offset, int max_drop) { const int size = kv_size(*vec); ks_introsort(cdec_score, size - offset, vec->a + offset); const int min_score = kv_A(*vec, offset).loc.score - max_drop; for (int i = offset; i < size; i++) { if (kv_A(*vec, i).loc.score < min_score) { vec->n = i; /* Free remaining */ for (int j = i; j < size; j++) free(kv_A(*vec, j).cigar); return; } } }
static inline void handle(pone_world* world, int sig) { pone_universe* universe = world->universe; if (kv_size(universe->signal_channels[sig]) == 0) { // There's no signal handlers. // Then, remove sigmask sigset_t set; sigemptyset(&set); sigaddset(&set, sig); CHECK_PTHREAD(pthread_sigmask(SIG_UNBLOCK, &set, NULL)); signal(sig, SIG_DFL); // Send signal to me. CHECK_PTHREAD(pthread_kill(pthread_self(), sig)); // restore sigmask sigfillset(&set); CHECK_PTHREAD(pthread_sigmask(SIG_BLOCK, &set, NULL)); } // Send signal to channels. pone_push_scope(world); pone_val* sig_v = pone_int_new(world, sig); for (pone_int_t i = 0; i < kv_size(universe->signal_channels[sig]); i++) { pone_val* chan = kv_A(universe->signal_channels[sig], i); if (!pone_chan_trysend(world, chan, sig_v)) { fprintf(stderr, "[pone] cannot send signal to channel(%p): signal:%d\n", chan, sig); // this may not critical error. } } pone_pop_scope(world); }
SkObject *sk_message_dispatch_simple(SkObject *self) { SkObject *result = NULL; bstring name = sk_string_get_bstring(sk_message_get_name(self)); /* is a string */ if(bchar(name, 0) == '"' && bchar(name, name->slen - 1) == '"') { return sk_string_from_bstring(self->vm, bmidstr(name, 1, name->slen - 2)); } /* is a number */ else if(is_number(name)) { return sk_number_create(self->vm, atoi(bstr2cstr(name, '\0'))); } /* is a command terminator. */ else if(biseqcstr(name, ";") == 1) { return NULL; } /* a message. */ else { int i; SkObjectList *callstack = sk_vm_callstack(SK_VM); for(i = kv_size(*callstack) - 1; i >= 0; i--) { SkObject *object = kv_A(*callstack, i); result = sk_object_dispatch_message(object, self); if(result) { return result; } } sk_printf("name: %s\n", name->data); sk_printf("thread: 0x%x\n", (unsigned int)pthread_self()); sk_exc_raise(SK_VM, sk_exception_create_lazy(SK_VM, "MessageError", bformat("Nobody is answering to the message '%s'.", name->data))); return NULL; } }
void shapes_free(shapes_v* shapes) { for(uint32_t i=0; i< kv_size(*shapes); i++) { shape_free(kv_A(*shapes, i)); } kv_destroy(*shapes); free(shapes); }
int main(void) { int a[4] = {50, 2, 1, 9}; int b[3] = {5, 50, 56}; vec_vec_u8_t vv = digify_array(b, 3); qsort (vv.a, 3, sizeof(vec_u8_t), compare_vec); for(size_t i = 0 ; i < kv_size(vv) ; i++) { printf("%d", undigify(kv_A(vv,i))); } printf("\n"); for(size_t i = 0 ; i < kv_size(vv) ; i++) { kv_destroy(kv_A(vv,i)); } kv_destroy(vv); return 0; }
vec_vec_u8_t digify_array(int *v, size_t n) { vec_vec_u8_t ret; kv_init(ret); kv_a(vec_u8_t, ret, n-1); for(size_t i = 0 ; i < n ; i ++) { kv_A(ret, i) = digify(v[i]); } return ret; }
int undigify(vec_u8_t v) { int ret = 0; int shift = 1; for(size_t i = 0 ; i < kv_size(v) ; i++) { ret += kv_A(v, i) * shift; shift *= 10; } return ret; }
/* search for local matching TValue v * return index of match, or -1 if not found */ int BijouBlock_find_local(BijouBlock *b, TValue v) { size_t i; for (i = 0; i < kv_size(b->locals); i++) { if (TValue_equal(v, kv_A(b->locals, i))) return i; } return -1; }
static void free_dellist(dl_list *dl) { unsigned int i; for (i = 0; i < kv_size(*dl); i++) free(kv_A(*dl, i)); kv_destroy(*dl); }
/* push a TValue into constants of block * returns index, or -1 if the value has * already been added */ int BijouBlock_push_const(BijouBlock *b, TValue v) { size_t i; for (i = 0; i < kv_size(b->k); ++i) { if (TValue_equal(kv_A(b->k, i), v)) return -1; } kv_push(TValue, b->k, v); return kv_size(b->k) - 1; }
static int delete_dellist(int fd, const char *cachedir, dl_list *dl, int total) { struct stat st; int retcode = EX_OK; int flag = 0; unsigned int count = 0, processed = 0; char *file, *relpath; count = kv_size(*dl); progressbar_start("Deleting files"); for (int i = 0; i < kv_size(*dl); i++) { flag = 0; relpath = file = kv_A(*dl, i); relpath += strlen(cachedir) + 1; if (fstatat(fd, relpath, &st, AT_SYMLINK_NOFOLLOW) == -1) { ++processed; progressbar_tick(processed, total); warn("can't stat %s", file); continue; } if (S_ISDIR(st.st_mode)) flag = AT_REMOVEDIR; if (unlinkat(fd, relpath, flag) == -1) { warn("unlink(%s)", file); retcode = EX_SOFTWARE; } free(file); kv_A(*dl, i) = NULL; ++processed; progressbar_tick(processed, total); } progressbar_tick(processed, total); if (!quiet) { if (retcode == EX_OK) printf("All done\n"); else printf("%d package%s could not be deleted\n", count, count > 1 ? "s" : ""); } return (retcode); }
/* push a TValue into local stack, returning * index of local */ int BijouBlock_push_local(BijouBlock *b, TValue v) { size_t i; for (i = 0; i < kv_size(b->locals); ++i) { if (TValue_equal(kv_A(b->locals, i), v)) return -1; } kv_push(TValue, b->locals, v); return kv_size(b->locals) - 1; }
static bool already_in_list(charlist *list, const char *pattern) { int i; for (i = 0; i < kv_size(*list); i++) if (strcmp(kv_A(*list, i), pattern) == 0) return (true); return (false); }
static void push_call(UI *ui, char *name, Array args) { Array call = ARRAY_DICT_INIT; UIData *data = ui->data; // To optimize data transfer(especially for "put"), we bundle adjacent // calls to same method together, so only add a new call entry if the last // method call is different from "name" if (kv_size(data->buffer)) { call = kv_A(data->buffer, kv_size(data->buffer) - 1).data.array; } if (!kv_size(call) || strcmp(kv_A(call, 0).data.string.data, name)) { call = (Array)ARRAY_DICT_INIT; ADD(data->buffer, ARRAY_OBJ(call)); ADD(call, STRING_OBJ(cstr_to_string(name))); } ADD(call, ARRAY_OBJ(args)); kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call; }
shapes_v* shapes_proj(const shapes_v* shapes, const char* from, const char* to) { shapes_v* projected = shapes_new(); for(uint32_t i=0; i<kv_size(*shapes); i++){ shape_t* p = shape_proj(kv_A(*shapes, i), from, to); shapes_add_shape(projected, p); } return projected; }
static int pkg_jobs_universe_process_deps(struct pkg_jobs_universe *universe, struct pkg *pkg, unsigned flags) { struct pkg_dep *d = NULL; int (*deps_func)(const struct pkg *pkg, struct pkg_dep **d); int rc; struct pkg_job_universe_item *unit; struct pkg *npkg, *rpkg; pkg_chain_t *rpkgs = NULL; bool found = false; rpkg = NULL; rc = EPKG_OK; if (flags & DEPS_FLAG_REVERSE) { deps_func = pkg_rdeps; } else { deps_func = pkg_deps; } while (deps_func(pkg, &d) == EPKG_OK) { HASH_FIND_STR(universe->items, d->uid, unit); if (unit != NULL) { continue; } rpkgs = NULL; npkg = NULL; if (!(flags & DEPS_FLAG_MIRROR)) { npkg = pkg_jobs_universe_get_local(universe, d->uid, 0); } if (!(flags & DEPS_FLAG_FORCE_LOCAL)) { /* Check for remote dependencies */ rpkgs = pkg_jobs_universe_get_remote(universe, d->uid, 0); } if (npkg == NULL && rpkgs == NULL) { pkg_emit_error("%s has a missing dependency: %s", pkg->name, d->name); if (flags & DEPS_FLAG_FORCE_MISSING) { continue; } return (EPKG_FATAL); } if (npkg != NULL) { if (pkg_jobs_universe_process_item(universe, npkg, &unit) != EPKG_OK) { continue; } } if (rpkgs == NULL) continue; /* * When processing deps, we should first try to select a dependency * from the same repo. * Otherwise, we would have ping-pong of dependencies instead of * the situation when this behaviour is handled by * CONSERVATIVE_UPGRADES. * * Important notes here: * 1. We are looking for packages that are dependencies of a package * `pkg` * 2. Now if `pkg` belongs to repo `r` and `rpkg` belongs to repo * `r` then we just select it. * 3. If `rpkg` is not found in `r` we just scan all packages */ /* * XXX: this is the proper place to expand flexible dependencies */ found = false; /* Iteration one */ for (int i = 0; i < kv_size(*rpkgs); i++) { rpkg = kv_A(*rpkgs, i); if (pkg->reponame && rpkg->reponame && strcmp (pkg->reponame, rpkg->reponame) == 0) { found = true; break; } } /* Fallback if a dependency is not found in the same repo */ if (!found) { for (int i = 0; i < kv_size(*rpkgs); i++) { rpkg = kv_A(*rpkgs, i); if (npkg != NULL) { /* Set reason for upgrades */ if (!pkg_jobs_need_upgrade(rpkg, npkg)) continue; /* Save automatic flag */ rpkg->automatic = npkg->automatic; } rc = pkg_jobs_universe_process_item(universe, rpkg, NULL); /* Special case if we cannot find any package */ if (npkg == NULL && rc != EPKG_OK) { kv_destroy(*rpkgs); free(rpkgs); return (rc); } } } else { assert (rpkg != NULL); if (npkg != NULL) { /* Set reason for upgrades */ if (!pkg_jobs_need_upgrade(rpkg, npkg)) continue; /* Save automatic flag */ rpkg->automatic = npkg->automatic; } rc = pkg_jobs_universe_process_item(universe, rpkg, NULL); if (npkg == NULL && rc != EPKG_OK) { kv_destroy(*rpkgs); free(rpkgs); return (rc); } } kv_destroy(*rpkgs); free(rpkgs); } return (EPKG_OK); }
static aln_v align_read(const kseq_t *read, const kseq_v targets, const size_t n_extra_targets, const kseq_v *extra_targets, const align_config_t *conf) { kseq_t *r; const int32_t read_len = read->seq.l; aln_v result; kv_init(result); kv_resize(aln_t, result, kv_size(targets)); uint8_t *read_num = calloc(read_len, sizeof(uint8_t)); for (int k = 0; k < read_len; ++k) read_num[k] = conf->table[(int)read->seq.s[k]]; // Align to each target kswq_t *qry = NULL; int min_score = -1000; int max_score = 0; for (size_t j = 0; j < kv_size(targets); j++) { // Encode target r = &kv_A(targets, j); aln_t aln = align_read_against_one(r, read_len, read_num, &qry, conf, min_score); if (aln.cigar != NULL) { max_score = aln.loc.score > max_score ? aln.loc.score : max_score; min_score = (aln.loc.score - conf->max_drop) > min_score ? (aln.loc.score - conf->max_drop) : min_score; kv_push(aln_t, result, aln); } } /* If no alignments to the first set of targets reached the minimum score, * abort. */ if (max_score < conf->min_score) { // kv_size returns the n field of a kvec_t, which is a size_t. for (size_t i = 0; i < kv_size(result); i++) free(kv_A(result, i).cigar); kv_size(result) = 0; free(qry); free(read_num); return result; } drop_low_scores(&result, 0, conf->max_drop); // Extra references - qe points to the exact end of the sequence int qend = kv_A(result, 0).loc.qe + 1; int read_len_trunc = read_len - qend; uint8_t *read_num_trunc = read_num + qend; free(qry); qry = NULL; if (read_len_trunc > 2) { for (size_t i = 0; i < n_extra_targets; i++) { const size_t idx = n_extra_targets - i - 1; min_score = -1000; const size_t init_count = kv_size(result); for (size_t j = 0; j < kv_size(extra_targets[idx]); j++) { r = &kv_A(extra_targets[idx], j); aln_t aln = align_read_against_one(r, read_len_trunc, read_num_trunc, &qry, conf, min_score); if (aln.cigar != NULL) { min_score = (aln.loc.score - conf->max_drop) > min_score ? (aln.loc.score - conf->max_drop) : min_score; aln.loc.qb += qend; aln.loc.qe += qend; kv_push(aln_t, result, aln); } } drop_low_scores(&result, init_count, conf->max_drop); /* Truncate */ const int alen = kv_A(result, init_count).loc.qe - kv_A(result, init_count).loc.qb; read_len_trunc = read_len_trunc - alen; free(qry); qry = NULL; } } free(qry); free(read_num); return result; }
void align_reads(const char *ref_path, const char *qry_path, const char *output_path, const int32_t match, /* 2 */ const int32_t mismatch, /* 2 */ const int32_t gap_o, /* 3 */ const int32_t gap_e, /* 1 */ const uint8_t n_threads, /* 1 */ const int32_t n_keep, const int32_t max_drop, const char *read_group, const char *read_group_id) { gzFile read_fp, ref_fp; FILE *out_fp; int32_t j, k, l; const int m = 5; kseq_t *seq; int8_t *mat = (int8_t *)calloc(25, sizeof(int8_t)); /* This table is used to transform nucleotide letters into numbers. */ uint8_t table[128] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; // initialize scoring matrix for genome sequences for(l = k = 0; LIKELY(l < 4); ++l) { for(j = 0; LIKELY(j < 4); ++j) mat[k++] = l == j ? match : -mismatch; /* weight_match : -weight_mismatch */ mat[k++] = 0; // ambiguous base } for(j = 0; LIKELY(j < 5); ++j) mat[k++] = 0; // Read reference sequences ref_fp = gzopen(ref_path, "r"); assert(ref_fp != NULL && "Failed to open reference"); seq = kseq_init(ref_fp); kseq_v ref_seqs; ref_seqs = read_seqs(seq, 0); kseq_destroy(seq); gzclose(ref_fp); fprintf(stderr, "[sw_align] Read %lu references\n", kv_size(ref_seqs)); // Print SAM header out_fp = fopen(output_path, "w"); fprintf(out_fp, "@HD\tVN:1.4\tSO:unsorted\n"); for(size_t i = 0; i < kv_size(ref_seqs); i++) { seq = &kv_A(ref_seqs, i); fprintf(out_fp, "@SQ\tSN:%s\tLN:%d\n", seq->name.s, (int32_t)seq->seq.l); } if(read_group) { fputs(read_group, out_fp); fputc('\n', out_fp); } align_config_t conf; conf.gap_o = gap_o; conf.gap_e = gap_e; conf.m = m; conf.table = table; conf.mat = mat; conf.n_keep = n_keep; conf.max_drop = max_drop; read_fp = gzopen(qry_path, "r"); assert(read_fp != NULL && "Failed to open query"); size_t count = 0; seq = kseq_init(read_fp); while(true) { kseq_v reads = read_seqs(seq, 5000 * n_threads); const size_t n_reads = kv_size(reads); if(!n_reads) { break; } worker_t *w = calloc(n_threads, sizeof(worker_t)); kstring_t *sams = calloc(n_reads, sizeof(kstring_t)); for(size_t i = 0; i < n_threads; i++) { w[i].start = i; w[i].n = n_reads; w[i].step = n_threads; w[i].ref_seqs = ref_seqs; w[i].reads = reads; w[i].sams = sams; w[i].config = &conf; w[i].read_group_id = read_group_id; } if(n_threads == 1) { worker(w); } else { pthread_t *tid = calloc(n_threads, sizeof(pthread_t)); for(size_t i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, worker, &w[i]); for(size_t i = 0; i < n_threads; ++i) pthread_join(tid[i], 0); } free(w); for(size_t i = 0; i < n_reads; i++) { fputs(sams[i].s, out_fp); free(sams[i].s); } free(sams); count += n_reads; kv_destroy(reads); } kseq_destroy(seq); fprintf(stderr, "[sw_align] Aligned %lu reads\n", count); // Clean up reference sequences kvi_destroy(kseq_stack_destroy, ref_seqs); gzclose(read_fp); fclose(out_fp); free(mat); }
static void write_sam_records(kstring_t *str, const kseq_t *read, const aln_v result, const char *read_group_id) { if (kv_size(result) == 0) return; /* Alignments are sorted by decreasing score */ bool wrote_primary_stuff = false; // can't any more use i==0 criterion, since the first match may be one with discordant cigar and read lengths aln_t *tmp_aln = NULL; // pointer to first alignment, so we can write a sensible target name to the dummy line for (size_t i = 0; i < kv_size(result); i++) { aln_t a = kv_A(result, i); if (i == 0) tmp_aln = &a; kstring_t tmpstr = {0, 0, NULL}; // temporary, so we can avoid writing to <str> until we know if the cigar and read are the same length ksprintf(&tmpstr, "%s\t%d\t", read->name.s, !wrote_primary_stuff ? 0 : 256); /* Secondary */ ksprintf(&tmpstr, "%s\t%d\t%d\t", a.target_name, /* Reference */ a.loc.tb + 1, /* POS */ 40); /* MAPQ */ if (a.loc.qb) ksprintf(&tmpstr, "%dS", a.loc.qb); size_t match_length = 0; for (int c = 0; c < a.n_cigar; c++) { int32_t letter = 0xf & *(a.cigar + c); int32_t length = (0xfffffff0 & *(a.cigar + c)) >> 4; ksprintf(&tmpstr, "%d", length); if (letter == 0) { ksprintf(&tmpstr, "M"); match_length += length; } else if (letter == 1) { ksprintf(&tmpstr, "I"); match_length += length; } else { ksprintf(&tmpstr, "D"); } } if(a.loc.qe - a.loc.qb != (int)match_length - 1) { fprintf(stderr, "[ig_align] Error: match length mismatch for query %s score %d target %s: qe - qb = %d - %d = %d != match_length - 1 = %zu\n", read->name.s, a.loc.score, a.target_name, a.loc.qe, a.loc.qb, a.loc.qe - a.loc.qb, match_length - 1); fprintf(stderr, " %s %s\n", tmpstr.s, read->seq.s); // assert(0); continue; } ksprintf(str, "%s", tmpstr.s); if (a.loc.qe + 1 != (int)read->seq.l) ksprintf(str, "%luS", read->seq.l - a.loc.qe - 1); ksprintf(str, "\t*\t0\t0\t"); ksprintf(str, "%s\t", wrote_primary_stuff ? "*" : read->seq.s); if (read->qual.s && !wrote_primary_stuff) ksprintf(str, "%s", read->qual.s); else ksprintf(str, "*"); ksprintf(str, "\tAS:i:%d\tNM:i:%d", a.loc.score, a.nm); if (read_group_id) ksprintf(str, "\tRG:Z:%s", read_group_id); kputs("\n", str); wrote_primary_stuff = true; } if (!wrote_primary_stuff) { // no matches whatsoever made it through (probably due to lots of cigar/read length discrepancies) -- write a dummy line so the code reading it knows we didn't just lose the query ksprintf(str, "%s\t%d\t%s\t%d\t%d\t%dS\t*\t0\t0\t%s\t*\tAS:i:%d\tNM:i:%d", read->name.s, 0, tmp_aln ? tmp_aln->target_name : "xxx", 1, 999, (int)read->seq.l, read->seq.s, 0, 0); if (read_group_id) ksprintf(str, "\tRG:Z:%s", read_group_id); kputs("\n", str); } }
OBJ TrCompiler_compile_node(VM, TrCompiler *c, TrBlock *b, TrNode *n, int reg) { if (!n) return TR_NIL; int start_reg = reg; REG(reg); b->line = n->line; /* TODO this shit is very repetitive, need to refactor */ switch (n->ntype) { case NODE_ROOT: case NODE_BLOCK: COMPILE_NODES(b, n->args[0], i, reg, 0); break; case NODE_VALUE: { int i = TrBlock_push_value(b, n->args[0]); PUSH_OP_ABx(b, LOADK, reg, i); } break; case NODE_STRING: { int i = TrBlock_push_string(b, TR_STR_PTR(n->args[0])); PUSH_OP_ABx(b, STRING, reg, i); } break; case NODE_ARRAY: { size_t size = 0; if (n->args[0]) { size = TR_ARRAY_SIZE(n->args[0]); /* compile args */ COMPILE_NODES(b, n->args[0], i, reg, i+1); ASSERT_NO_LOCAL_IN(Array); } PUSH_OP_AB(b, NEWARRAY, reg, size); } break; case NODE_HASH: { size_t size = 0; if (n->args[0]) { size = TR_ARRAY_SIZE(n->args[0]); /* compile args */ COMPILE_NODES(b, n->args[0], i, reg, i+1); ASSERT_NO_LOCAL_IN(Hash); } PUSH_OP_AB(b, NEWHASH, reg, size/2); } break; case NODE_RANGE: { COMPILE_NODE(b, n->args[0], reg); COMPILE_NODE(b, n->args[1], reg+1); REG(reg+1); ASSERT_NO_LOCAL_IN(Range); PUSH_OP_ABC(b, NEWRANGE, reg, reg+1, n->args[2]); } break; case NODE_ASSIGN: { OBJ name = n->args[0]; COMPILE_NODE(b, n->args[1], reg); if (TrBlock_find_upval_in_scope(b, name) != -1) { /* upval */ int i = TrBlock_push_upval(b, name); PUSH_OP_AB(b, SETUPVAL, reg, i); } else { /* local */ int i = TrBlock_push_local(b, name); TrInst *last_inst = &kv_A(b->code, kv_size(b->code) - 1); switch (GET_OPCODE(*last_inst)) { case TR_OP_ADD: /* Those instructions can load direcly into a local */ case TR_OP_SUB: case TR_OP_LT: case TR_OP_NEG: case TR_OP_NOT: SETARG_A(*last_inst, i); break; default: if (i != reg) PUSH_OP_AB(b, MOVE, i, reg); } } } break; case NODE_SETIVAR: COMPILE_NODE(b, n->args[1], reg); PUSH_OP_ABx(b, SETIVAR, reg, TrBlock_push_value(b, n->args[0])); break; case NODE_GETIVAR: PUSH_OP_ABx(b, GETIVAR, reg, TrBlock_push_value(b, n->args[0])); break; case NODE_SETCVAR: COMPILE_NODE(b, n->args[1], reg); PUSH_OP_ABx(b, SETCVAR, reg, TrBlock_push_value(b, n->args[0])); break; case NODE_GETCVAR: PUSH_OP_ABx(b, GETCVAR, reg, TrBlock_push_value(b, n->args[0])); break; case NODE_SETGLOBAL: COMPILE_NODE(b, n->args[1], reg); PUSH_OP_ABx(b, SETGLOBAL, reg, TrBlock_push_value(b, n->args[0])); break; case NODE_GETGLOBAL: PUSH_OP_ABx(b, GETGLOBAL, reg, TrBlock_push_value(b, n->args[0])); break; case NODE_SEND: /* can also be a variable access */ { TrNode *msg = (TrNode *)n->args[1]; OBJ name = msg->args[0]; assert(msg->ntype == NODE_MSG); int i; /* local */ if ((i = TrBlock_find_local(b, name)) != -1) { if (reg != i) PUSH_OP_AB(b, MOVE, reg, i); /* upval */ } else if (TrBlock_find_upval_in_scope(b, name) != -1) { i = TrBlock_push_upval(b, name); PUSH_OP_AB(b, GETUPVAL, reg, i); /* method call */ } else { /* receiver */ if (n->args[0]) COMPILE_NODE(b, n->args[0], reg); else PUSH_OP_A(b, SELF, reg); i = TrBlock_push_value(b, name); /* args */ size_t argc = 0; if (msg->args[1]) { argc = TR_ARRAY_SIZE(msg->args[1]) << 1; TR_ARRAY_EACH(msg->args[1], i, v, { TrNode *arg = (TrNode *)v; assert(arg->ntype == NODE_ARG); reg += COMPILE_NODE(b, arg->args[0], reg+i+2); if (arg->args[1]) argc |= 1; /* splat */ }); ASSERT_NO_LOCAL_IN(arguments); } /* block */ size_t blki = 0; TrBlock *blk = 0; if (n->args[2]) { blk = TrBlock_new(c, b); TrNode *blkn = (TrNode *)n->args[2]; blki = kv_size(b->blocks) + 1; blk->argc = 0; if (blkn->args[1]) { blk->argc = TR_ARRAY_SIZE(blkn->args[1]); /* add parameters as locals in block context */ TR_ARRAY_EACH(blkn->args[1], i, v, { TrNode *param = (TrNode *)v; TrBlock_push_local(blk, param->args[0]); });
static aln_v align_read(const kseq_t *read, const kseq_v targets, const align_config_t *conf) { kseq_t *r; const int32_t read_len = read->seq.l; aln_v result; kv_init(result); kv_resize(aln_t, result, kv_size(targets)); uint8_t *read_num = calloc(read_len, sizeof(uint8_t)); for(size_t k = 0; k < read_len; ++k) read_num[k] = conf->table[(int)read->seq.s[k]]; // Align to each target kswq_t *qry = NULL; for(size_t j = 0; j < kv_size(targets); j++) { // Encode target r = &kv_A(targets, j); uint8_t *ref_num = calloc(r->seq.l, sizeof(uint8_t)); for(size_t k = 0; k < r->seq.l; ++k) ref_num[k] = conf->table[(int)r->seq.s[k]]; aln_t aln; aln.target_idx = j; aln.loc = ksw_align(read_len, read_num, r->seq.l, ref_num, conf->m, conf->mat, conf->gap_o, conf->gap_e, KSW_XSTART, &qry); ksw_global(aln.loc.qe - aln.loc.qb + 1, &read_num[aln.loc.qb], aln.loc.te - aln.loc.tb + 1, &ref_num[aln.loc.tb], conf->m, conf->mat, conf->gap_o, conf->gap_e, 50, /* TODO: Magic number - band width */ &aln.n_cigar, &aln.cigar); aln.nm = 0; size_t qi = aln.loc.qb, ri = aln.loc.tb; for(size_t k = 0; k < aln.n_cigar; k++) { const int32_t oplen = bam_cigar_oplen(aln.cigar[k]), optype = bam_cigar_type(aln.cigar[k]); if(optype & 3) { // consumes both - check for mismatches for(size_t j = 0; j < oplen; j++) { if(UNLIKELY(read_num[qi + j] != ref_num[ri + j])) aln.nm++; } } else { aln.nm += oplen; } if(optype & 1) qi += oplen; if(optype & 2) ri += oplen; } kv_push(aln_t, result, aln); free(ref_num); } free(qry); free(read_num); ks_introsort(dec_score, kv_size(result), result.a); return result; }
int do_grep() { #ifdef DEBUGa printf("[!]do_grep\n"); #endif BamInfo_t *pbam; kh_cstr_t BamID; khiter_t ki, bami; kstring_t ks1 = { 0, 0, NULL }; kstring_t ks2 = { 0, 0, NULL }; kstring_t ks3 = { 0, 0, NULL }; samFile *in; bam_hdr_t *h; hts_idx_t *idx; bam1_t *b, *d, *d2, *bR1, *bR2, *bR3; bR1 = bam_init1(); bR2 = bam_init1(); bR3 = bam_init1(); //htsFile *out; //hts_opt *in_opts = NULL, *out_opts = NULL; int r = 0, exit_code = 0; kvec_t(bam1_t) R1, R2, RV; pierCluster_t *pierCluster; //samdat_t tmp_samdat; FILE *fs = fopen("./test.txt","w"); for (bami = kh_begin(bamNFOp); bami != kh_end(bamNFOp); ++bami) { //printf(">[%d]:\n",bami); if (kh_exist(bamNFOp, bami)) { kv_init(R1); kv_init(R2); kv_init(RV); //tmp_samdat = (const samdat_t){ 0 }; //memset(&tmp_samdat,0,sizeof(samdat_t)); //printf("-[%d]:\n",bami); BamID = kh_key(bamNFOp, bami); pbam = &kh_value(bamNFOp, bami); fprintf(stderr, "%u [%s]=%s\t%u %u\n",bami,BamID,pbam->fileName,pbam->insertSize,pbam->SD); in = sam_open(pbam->fileName, "r"); if (in == NULL) { fprintf(stderr, "[x]Error opening \"%s\"\n", pbam->fileName); return EXIT_FAILURE; } h = sam_hdr_read(in); /* out = hts_open("-", "w"); if (out == NULL) { fprintf(stderr, "[x]Error opening standard output\n"); return EXIT_FAILURE; } if (sam_hdr_write(out, h) < 0) { fprintf(stderr, "[!]Error writing output header.\n"); exit_code = 1; } */ int8_t *ChrIsHum; if (h == NULL) { fprintf(stderr, "[x]Couldn't read header for \"%s\"\n", pbam->fileName); return EXIT_FAILURE; } else { ChrIsHum = malloc(h->n_targets * sizeof(int8_t)); for (int32_t i=0; i < h->n_targets; ++i) { //ChrIsHum[i] = -1; ki = kh_get(chrNFO, chrNFOp, h->target_name[i]); if (ki == kh_end(chrNFOp)) { errx(4,"[x]Cannot find ChrID for [%s] !",h->target_name[i]); } else { ChrInfo_t * tmp = &kh_value(chrNFOp, ki); ChrIsHum[i] = tmp->isHum; //printf(">>> %d Chr:%s %d\n",i,h->target_name[i],ChrIsHum[i]); } } } h->ignore_sam_err = 0; b = bam_init1(); d = bam_init1(); d2 = bam_init1(); if ((idx = sam_index_load(in, pbam->fileName)) == 0) { fprintf(stderr, "[E::%s] fail to load the BAM index\n", __func__); return 1; } pierCluster = sam_plp_init(); while ((r = sam_read1(in, h, b)) >= 0) { int8_t flag = false; const bam1_core_t *c = &b->core; if (c->flag & BAM_FSECONDARY) continue; if (c->n_cigar) { uint32_t *cigar = bam_get_cigar(b); for (int i = 0; i < c->n_cigar; ++i) { if (bam_cigar_opchr(cigar[i])=='S') { // soft clipping if ( bam_cigar_oplen(cigar[i]) >= myConfig.minGrepSlen ) { flag = true; } } } } if (flag && ChrIsHum[c->tid]) { // Now, skip Virus items. //bam_copy1(bR1, b); flag = 0; // recycle //int enoughMapQ = 0; //kstring_t ks = { 0, 0, NULL }; /*if (sam_format1(h, b, &ks1) < 0) { fprintf(stderr, "Error writing output.\n"); exit_code = 1; break; } else*/ if ((c->mtid == c->tid && ChrIsHum[c->tid]) || (ChrIsHum[c->tid] ^ ChrIsHum[c->mtid])) { // Only grep those mapped on same Human ChrID, or diff species/一方在病毒的情况. //printf(">[%s]\n",ks_str(&ks1)); flag |= 1; //tmp_samdat.b = bam_dup1(b); //kv_push(samdat_t,R1,tmp_samdat); /*if (checkMapQ(ChrIsHum, b, true)) { ++enoughMapQ; }*/ } if (getPairedSam(in, idx, b, d) != 0) { flag &= ~1; continue; } else { flag |= 2; /*if (checkMapQ(ChrIsHum, d, false)) { ++enoughMapQ; }*/ /*if (c->flag & BAM_FSECONDARY) { if (getPairedSam(in, idx, d, d2) == 0) { //sam_format1(h, d2, &ks3); flag |= 4; if (checkMapQ(ChrIsHum, d2, false)) { ++enoughMapQ; } } }*/ } /* 对于 BAM_FSECONDARY(256) 的 Read,跳两次 与 读 SA 项,效果一样。 >[sf95_Ref_48245009_48245108_48245208_Vir_-_2000_2044_R_100_90 353 chr2 13996555 0 50S40M chr18 48245109 0ACACAACAATGTTCCGGAGACTCTAAGGCCTCCCGATACAGAGCAGAGGCCACACACACACACACCATGGAATACTATTCAGCCAAAAAA CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC NM:i:0 MD:Z:40 AS:i:40 XS:i:40 RG:Z:Fsimout_mB SA:Z:rgi|59585|emb|X04615.1|,2000,-,40S46M4S,60,0; YC:Z:CT YD:Z:f] -[sf95_Ref_48245009_48245108_48245208_Vir_-_2000_2044_R_100_90 177 chr18 48245109 9 40S50M gi|59585|emb|X04615.1|2000 0 GTTCCGGAGACTCTAAGGCCTCCCGATACAGAGCAGAGGCCACACACACACACACCATGGAATACTATTCAGCCAAAAAAAGGAATTCAA CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC NM:i:0 MD:Z:50 AS:i:50 XS:i:46 RG:Z:Fsimout_mB SA:Z:rgi|59585|emb|X04615.1|,2000,+,50S40M,9,0; YC:Z:GA YD:Z:f] +[sf95_Ref_48245009_48245108_48245208_Vir_-_2000_2044_R_100_90 113 gi|59585|emb|X04615.1| 2000 60 40S46M4S chr18 48245109 0 TTTTTTGGCTGAATAGTATTCCATGGTGTGTGTGTGTGTGGCCTCTGCTCTGTATCGGGAGGCCTTAGAGTCTCCGGAACATTGTTGTGT CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC NM:i:0 MD:Z:46 AS:i:46 XS:i:27 RG:Z:Fsimout_mB SA:Z:fchr2,13996555,+,50S40M,0,0; YC:Z:CT YD:Z:r] */ /*if (sam_format1(h, d, &ks2) < 0) { fprintf(stderr, "Error writing output.\n"); exit_code = 1; break; }*/ if (((flag & 3) == 3) /*&& enoughMapQ >= myConfig.samples*/) { /*printf(">%d[%s]\n",checkMapQ(ChrIsHum, b, true),ks_str(&ks1)); printf("-%d[%s]\n",checkMapQ(ChrIsHum, d, false),ks_str(&ks2)); if (flag & 4) { printf("+%d[%s]\n",checkMapQ(ChrIsHum, d2, false),ks_str(&ks3)); } printf("<--%d\n",enoughMapQ);*/ if (sam_plp_push(ChrIsHum, pierCluster, b) == 0) { //printf("--HumRange=%s:%d-%d\n", h->target_name[(pierCluster->HumanRange).tid], (pierCluster->HumanRange).pos, (pierCluster->HumanRange).endpos); if ((!ChrIsHum[(d->core).tid]) && (flag & 2)) sam_plp_push(ChrIsHum, pierCluster, d); //if ((!ChrIsHum[(d2->core).tid]) && (flag & 4)) sam_plp_push(ChrIsHum, pierCluster, d2); } else { //print fprintf(fs,"[%s]\nHumRange=%s:%d-%d\n", BamID, h->target_name[(pierCluster->HumanRange).tid], (pierCluster->HumanRange).pos, (pierCluster->HumanRange).endpos); fprintf(fs,"VirRange=%s:%d-%d\n", h->target_name[(pierCluster->VirusRange).tid], (pierCluster->VirusRange).pos, (pierCluster->VirusRange).endpos); for (size_t i=0; i<kv_size(pierCluster->Reads);++i) { bam1_t *bi = kv_A(pierCluster->Reads, i); if (sam_format1(h, bi, &ks1) < 0) { fprintf(stderr, "Error writing output.\n"); exit_code = 1; break; } else { fprintf(fs,"%s\n",ks1.s); } } fprintf(fs,"\n"); //printf("HumRange=%s:%d-%d\n", h->target_name[(pierCluster->HumanRange).tid], (pierCluster->HumanRange).pos, (pierCluster->HumanRange).endpos); //fflush(fs); sam_plp_dectroy(pierCluster); pierCluster = sam_plp_init(); } } } /*char *qname = bam_get_qname(b); if (sam_write1(out, h, b) < 0) { fprintf(stderr, "[x]Error writing output.\n"); exit_code = 1; break; }*/ } /* r = sam_close(out); // stdout can only be closed once if (r < 0) { fprintf(stderr, "Error closing output.\n"); exit_code = 1; } */ hts_idx_destroy(idx); bam_destroy1(b); bam_destroy1(d); bam_destroy1(d2); bam_hdr_destroy(h); r = sam_close(in); free(ChrIsHum); #ifdef DEBUGa fflush(NULL); //pressAnyKey(); #endif sam_plp_dectroy(pierCluster); //printf("<[%d]:\n",bami); } } fclose(fs); getPairedSam(NULL, NULL, NULL, NULL); // sam_close(fp2); //printf("---[%d]---\n",exit_code); bam_destroy1(bR1); bam_destroy1(bR2); bam_destroy1(bR3); ks_release(&ks1); ks_release(&ks2); ks_release(&ks3); return exit_code; }
/* returns instruction at index, or -1 if index is greater * than number of instructions */ bInst BijouBlock_fetch_instruction(BijouBlock *b, int index) { if (index >= (int)kv_size(b->code)) return -1; return kv_A(b->code, index); }
int exec_which(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; char pathabs[MAXPATHLEN]; char *p, *path, *match, *savedpath; int ret = EPKG_OK, retcode = EX_SOFTWARE; int ch, i; int res, pathlen = 0; bool orig = false; bool glob = false; bool search = false; bool search_s = false; charlist patterns; struct option longopts[] = { { "glob", no_argument, NULL, 'g' }, { "origin", no_argument, NULL, 'o' }, { "path-search", no_argument, NULL, 'p' }, { "quiet", no_argument, NULL, 'q' }, { NULL, 0, NULL, 0 }, }; path = NULL; while ((ch = getopt_long(argc, argv, "+gopq", longopts, NULL)) != -1) { switch (ch) { case 'g': glob = true; break; case 'o': orig = true; break; case 'p': search_s = true; break; case 'q': quiet = true; break; default: usage_which(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_which(); return (EX_USAGE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (search_s) { if ((path = getenv("PATH")) == NULL) { printf("$PATH is not set, falling back to non-search behaviour\n"); search_s = false; } else { pathlen = strlen(path) + 1; } } while (argc >= 1) { kv_init(patterns); retcode = EX_SOFTWARE; if (search_s) { if ((argv[0][0] == '.') || (argv[0][0] == '/')) { search = false; } else { search = true; if (strlen(argv[0]) >= FILENAME_MAX) { retcode = EX_USAGE; goto cleanup; } p = malloc(pathlen); if (p == NULL) { retcode = EX_OSERR; goto cleanup; } strlcpy(p, path, pathlen); match = NULL; savedpath=p; for (;;) { res = get_match(&match, &p, argv[0]); if (p == NULL) break; if (res == (EX_USAGE)) { printf("%s was not found in PATH, falling back to non-search behaviour\n", argv[0]); search = false; } else if (res == (EX_OSERR)) { retcode = EX_OSERR; free(savedpath); goto cleanup; } else { pkg_absolutepath(match, pathabs, sizeof(pathabs)); /* ensure not not append twice an entry if PATH is messy */ if (already_in_list(&patterns, pathabs)) continue; kv_push(char *, patterns, strdup(pathabs)); free(match); } } free(savedpath); } } if (!glob && !search) { pkg_absolutepath(argv[0], pathabs, sizeof(pathabs)); kv_push(char *, patterns, strdup(pathabs)); } else if (!search) { if (strlcpy(pathabs, argv[0], sizeof(pathabs)) >= sizeof(pathabs)) { retcode = EX_USAGE; goto cleanup; } } for (i = 0; i < kv_size(patterns); i++) { if ((it = pkgdb_query_which(db, kv_A(patterns, i), glob)) == NULL) { retcode = EX_IOERR; goto cleanup; } pkg = NULL; while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) { retcode = EX_OK; if (quiet && orig) pkg_printf("%o\n", pkg); else if (quiet && !orig) pkg_printf("%n-%v\n", pkg, pkg); else if (!quiet && orig) pkg_printf("%S was installed by package %o\n", kv_A(patterns, i), pkg); else if (!quiet && !orig) pkg_printf("%S was installed by package %n-%v\n", kv_A(patterns, i), pkg, pkg); } if (retcode != EX_OK && !quiet) printf("%s was not found in the database\n", kv_A(patterns, i)); pkg_free(pkg); pkgdb_it_free(it); } kv_destroy(patterns); argc--; argv++; } cleanup: pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); return (retcode); }
void BijouBlock_dump2(VM, BijouBlock* b, int level) { char * str; size_t x; INDENT; printf("; block at: %p, %s (level %d)\n", (void *)b, b->funcname != NULL ? b->funcname : "", level); INDENT; printf("; %zu registers\n", b->regc); INDENT; printf("; constants (%zu)\n", kv_size(b->k)); for (x = 0; x < kv_size(b->k); ++x) { str = TValue_to_string(kv_A(b->k, x)); int s = ttisstring(&kv_A(b->k, x)); INDENT; printf("\t%zu: (%s) %s%s%s\n", x, TValue_type_to_string(kv_A(b->k, x)), s ? "\"" : "", str, s ? "\"" : ""); if (ttisnumber(&kv_A(b->k, x))) B_FREE(str); } INDENT; printf("; locals (%zu)\n", kv_size(b->locals)); for (x = 0; x < kv_size(b->locals); ++x) { str = TValue_to_string(kv_A(b->locals, x)); INDENT; printf("\t%zu: (%s) %s\n", x, TValue_type_to_string(kv_A(b->locals, x)), str); if (ttisnumber(&kv_A(b->locals, x))) B_FREE(str); } INDENT; printf("; upvals (%zu)\n", kv_size(b->upvals)); for (x = 0; x < kv_size(b->upvals); ++x) { str = TValue_to_string(kv_A(b->upvals, x)); INDENT; printf("\t%zu: (%s) %s\n", x, TValue_type_to_string(kv_A(b->upvals, x)), str); if (ttisnumber(&kv_A(b->upvals, x))) B_FREE(str); } INDENT; printf("; code section (%zu instructions)\n", kv_size(b->code)); for (x = 0; x < kv_size(b->code); ++x) { bInst i = kv_A(b->code, x); INDENT; print_op(i); printf("\t"); switch (GET_OPCODE(i)) { case OP_MOVE: printf("; R[%d] = R[%d]", GETARG_A(i), GETARG_B(i)); break; case OP_LOADK: printf("; R[%d] = K[%d]", GETARG_A(i), GETARG_Bx(i)); break; case OP_LOADBOOL: printf("; R[%d] = %s", GETARG_A(i), GETARG_B(i) == 0 ? "false" : "true" ); break; case OP_LOADNULL: printf("; R[%d] = null", GETARG_A(i)); break; case OP_GETGLOBAL: printf("; R[%d] = globals[K[%d]]", GETARG_A(i), GETARG_Bx(i)); break; case OP_SETGLOBAL: printf("; globals[K[%d]] = R[%d]", GETARG_Bx(i), GETARG_A(i)); break; case OP_GETLOCAL: printf("; R[%d] = locals[K[%d]]", GETARG_A(i), GETARG_Bx(i)); break; case OP_SETLOCAL: printf("; locals[K[%d]] = R[%d]", GETARG_Bx(i), GETARG_A(i)); break; case OP_ADD: printf("; R[%d] = RK[%d] + RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_SUB: printf("; R[%d] = RK[%d] - RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_MUL: printf("; R[%d] = RK[%d] * RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_DIV: printf("; R[%d] = RK[%d] / RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_POW: printf("; R[%d] = RK[%d] ** RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_REM: printf("; R[%d] = RK[%d] %% RK[%d]", GETARG_A(i), GETARG_B(i), GETARG_C(i)); break; case OP_UNM: printf("; R[%d] = -RK[%d]", GETARG_A(i), GETARG_B(i)); break; case OP_NOT: printf("; R[%d] = !RK[%d]", GETARG_A(i), GETARG_B(i)); break; case OP_CLOSURE: printf("; R[%d] = ", GETARG_A(i)); if (ISK(GETARG_Bx(i))) { BijouFunction *func = kv_A(vm->functions, GETARG_Bx(i) & ~0x100); printf("%s\n", func->name); } else printf("closure[%d] (%s)\n", GETARG_Bx(i), b->children[GETARG_Bx(i)]->funcname); break; case OP_CALL: printf("; R[%d] = R[%d](", GETARG_A(i), GETARG_B(i)); size_t x; for (x = 0; x < GETARG_C(i); ++x) { printf("R[%zu], ", x); } if (x > 0) { printf("\b\b"); } printf(")"); break; case OP_GETEXTERNAL: printf("; R[%d] = closure(K[%d])", GETARG_A(i), GETARG_B(i)); break; } printf("\n"); } INDENT; printf("; functions (%zu definitions)\n", b->numchildren); for (x = 0; x < b->numchildren; ++x) { BijouBlock_dump2(vm, b->children[x], level + 1); } }