size_t vaspack(char **bufferp, size_t maxlen, const char *tmpl, va_list args) { /* TODO: This function is a bit inefficient, as it traverses the template * twice. Better would be a new type of stream which allocates buffer chunks * as it goes, and returns them all joined up at the end */ PackStream *countstream = packstream_string_new(NULL, 0); va_list countargs; va_copy(countargs, args); size_t len = vpack(countstream, tmpl, countargs); packstream_string_free(countstream); va_end(countargs); if(len < 0) return len; if(maxlen && len > maxlen) len = maxlen; *bufferp = malloc(len); if(!*bufferp) return -1; return vsnpack(*bufferp, len, tmpl, args); }
int closure_execlpiv(closure_t *closure, pointer cell, void *ptr, int id, const char *fmt, va_list args) { pointer head, tmp, result; scheme *sc = closure->sc; /* Convert the C args to Scheme. */ if (fmt) { head = vpack(sc, fmt, args); } else { head = sc->NIL; } /* Protect the list while allocating cells. */ tmp = head; if (tmp != sc->NIL) { sc->vptr->protect(sc, tmp); } /* Prepend the cell, ptr and id to the arg list. */ head = _cons(sc, scm_mk_integer(sc, id), head, 0); head = _cons(sc, scm_mk_ptr(sc, ptr), head, 0); head = _cons(sc, cell, head, 0); /* Unprotect the list now that we're done allocating. */ if (tmp != sc->NIL) { sc->vptr->unprotect(sc, tmp); } /* Evaluate the closure. */ result = closure_exec_with_scheme_args(closure, head); /* Translate the result to an int. */ return closure_translate_result(closure->sc, result); }
ptr tex::vsplit(int n, scal h) { ptr p; ptr q; ptr v; v = box(n); if (split_first_mark != null) { delete_token_ref(split_first_mark); split_first_mark = null; delete_token_ref(split_bot_mark); split_bot_mark = null; } if (v == null) return null; if (type(v) != VLIST_NODE) { print_err(null_str); print_esc("vsplit"); print(" needs a "); print_esc("vbox"); help_vsplit_vbox(); error(); return null; } q = vert_break(list_ptr(v), h, split_max_depth); p = list_ptr(v); if (p == q) { list_ptr(v) = null; } else { loop { if (type(p) == MARK_NODE) { if (split_first_mark == null) { split_first_mark = mark_ptr(p); split_bot_mark = split_first_mark; token_ref_count(split_first_mark) += 2; } else { delete_token_ref(split_bot_mark); split_bot_mark = mark_ptr(p); add_token_ref(split_bot_mark); } } if (link(p) == q) { link(p) = null; break; } p = link(p); } } q = prune_page_top(q); p = list_ptr(v); free_node(v, BOX_NODE_SIZE); if (q == null) { box(n) = null; } else { box(n) = vpack(q, 0, ADDITIONAL); } return (vpackage(p, h, EXACTLY, split_max_depth)); }
size_t vsnpack(char *buffer, size_t buflen, const char *tmpl, va_list args) { PackStream *ss = packstream_string_new(buffer, buflen); size_t ret = vpack(ss, tmpl, args); packstream_string_free(ss); return ret; }
bool tex::insert_box(ptr p) { bool wait; ptr q, r, t; int n; q = link(page_ins_head); while (subtype(q) != subtype(p)) q = link(q); if (best_ins_ptr(q) == null) return TRUE; wait = FALSE; r = last_ins_ptr(q); link(r) = ins_ptr(p); if (best_ins_ptr(q) == p) { if (type(q) == SPLIT_UP && broken_ins(q) == p && broken_ptr(q) != null) { while (link(r) != broken_ptr(q)) r = link(r); link(r) = null; split_top_skip = split_top_ptr(p); ins_ptr(p) = prune_page_top(broken_ptr(q)); if (ins_ptr(p) != null) { t = vpack(ins_ptr(p), 0, ADDITIONAL); ins_height(p) = box_height(t) + box_depth(t); free_node(t, BOX_NODE_SIZE); wait = TRUE; } } best_ins_ptr(q) = null; n = subtype(q); t = list_ptr(box(n)); free_node(box(n), BOX_NODE_SIZE); box(n) = vpack(t, 0, ADDITIONAL); } else { while (link(r) != null) r = link(r); last_ins_ptr(q) = r; } return wait; }
int pack(uchar *b, uchar *p, uchar *e, char *f, ...) { va_list a; int r; va_start(a, f); r = vpack(b, p, e, f, a); va_end(a); return r; }
/** * Evaluate a Scheme procedure with C-style varargs. * @param closure The procedure to evaluate. * @param fmt Character encoding for the args, similar to printf, but the codes * are different. See kern.c's vpack() function. * @returns The Scheme result of evaluation. */ pointer closure_execv(closure_t *closure, const char *fmt, va_list args) { pointer head; /* Convert the C args to Scheme. */ if (fmt) { head = vpack(closure->sc, fmt, args); } else { head = closure->sc->NIL; } return closure_exec_with_scheme_args(closure, head); }
int closure_execvl(closure_t *closure, const char *fmt, va_list args, pointer cell) { pointer head, result; scheme *sc = closure->sc; /* Convert the C args to Scheme. */ if (fmt) { head = vpack(sc, fmt, args); } else { head = sc->NIL; } /* Append args to the list */ if (head == sc->NIL) { /* args is the only thing on the list */ head = _cons(sc, cell, sc->NIL, 0); } else { /* Protect the list while allocating for _cons */ sc->vptr->protect(sc, head); /* Find the end of the list */ pointer tail = head; while (scm_cdr(sc, tail) != sc->NIL) { tail = scm_cdr(sc, tail); } /* Append the args to the tail of the list */ tail->_object._cons._cdr = _cons(sc, cell, sc->NIL, 0); /* Unprotect the list now that we're done allocating. */ sc->vptr->unprotect(sc, head); } /* Evaluate the closure. */ result = closure_exec_with_scheme_args(closure, head); /* Translate the result to an int. */ return closure_translate_result(closure->sc, result); }
void tex::handle_right_brace () { scal d; int f; ptr p; ptr q; switch (cur_group) { case SIMPLE_GROUP: unsave(); break; case BOTTOM_LEVEL: print_err("Too many }'s"); help_close_group(); error(); break; case SEMI_SIMPLE_GROUP: case MATH_SHIFT_GROUP: case MATH_LEFT_GROUP: extra_right_brace(); break; case HBOX_GROUP: package(0); break; case ADJUSTED_HBOX_GROUP: tex::adjust_tail = tex::adjust_head; package(0); break; case VBOX_GROUP: end_graf(); package(0); break; case VTOP_GROUP: end_graf(); package(VTOP_CODE); break; case INSERT_GROUP: end_graf(); q = split_top_skip; add_glue_ref(q); d = split_max_depth; f = floating_penalty; unsave(); decr(save_ptr); p = vpack(link(head), 0, ADDITIONAL); pop_nest(); if (saved(0) < 255) { tail_append(new_node(INS_NODE_SIZE)); type(tail) = INS_NODE; subtype(tail) = saved(0); ins_height(tail) = box_height(p) + box_depth(p); ins_ptr(tail) = list_ptr(p); split_top_ptr(tail) = q; ins_depth(tail) = d; float_cost(tail) = f; } else { tail_append(new_node(SMALL_NODE_SIZE)); type(tail) = ADJUST_NODE; subtype(tail) = 0; adjust_ptr(tail) = list_ptr(p); delete_glue_ref(q); } free_node(p, BOX_NODE_SIZE); if (nest_ptr == nest) build_page(); break; case OUTPUT_GROUP: if (loc != null || (token_type != OUTPUT_TEXT && token_type != BACKED_UP)) { print_err("Unbalanced output routine"); help_output_balance(); error(); do get_token(); while (loc != null); } end_token_list(); end_graf(); unsave(); output_active = FALSE; insert_penalties = 0; if (box(255) != null) { print_err("Output routine didn't use all of "); print_esc("box255"); help_output(); box_error(255); } if (tail != head) { link(page_tail) = link(head); page_tail = tail; } if (link(page_head) != null) { if (link(contrib_head) == null) contrib_tail = page_tail; link(page_tail) = link(contrib_head); link(contrib_head) = link(page_head); link(page_head) = null; page_tail = page_head; } pop_nest(); build_page(); break; case DISC_GROUP: build_discretionary(); break; case ALIGN_GROUP: back_input(); cur_tok = sym2tok(FROZEN_CR); print_err("Missing "); print_esc("cr"); print(" inserted"); help_align_cr(); ins_error(); break; case NO_ALIGN_GROUP: end_graf(); unsave(); align_peek(); break; case VCENTER_GROUP: end_graf(); unsave(); save_ptr -= 2; p = vpackage(link(head), saved(1), saved(0), MAX_DIMEN); pop_nest(); tail_append(new_noad()); type(tail) = VCENTER_NOAD; math_type(nucleus(tail)) = SUB_BOX; info(nucleus(tail)) = p; break; case MATH_CHOICE_GROUP: build_choices(); break; case MATH_GROUP: unsave(); decr(save_ptr); math_type(saved(0)) = SUB_MLIST; p = fin_mlist(null); math_link(saved(0)) = p; if (p != null) { if (link(p) == null) { if (type(p) == ORD_NOAD) { if (math_type(subscr(p)) == EMPTY && math_type(supscr(p)) == EMPTY) { mcopy(saved(0), nucleus(p)); free_node(p, NOAD_SIZE); } } else if (type(p) == ACCENT_NOAD && saved(0) == nucleus(tail) && type(tail) == ORD_NOAD) { q = head; while (link(q) != tail) q = link(q); link(q) = p; free_node(tail, NOAD_SIZE); tail = p; } } } break; default: confusion("rightbrace"); break; } }