コード例 #1
0
ファイル: extensions.c プロジェクト: clerkma/texlive-mobile
void expand_macros_in_tokenlist(halfword p)
{
int old_mode;
pointer q= get_avail();
pointer r= get_avail();
token_info(q)= right_brace_token+'}';
token_link(q)= r;
token_info(r)= end_write_token;
begin_token_list(q,inserted);
begin_token_list(write_tokens(p),write_text);
q= get_avail();
token_info(q)= left_brace_token+'{';
begin_token_list(q,inserted);


old_mode= mode;
mode= 0;

cur_cs= write_loc;
q= scan_toks(false,true);
get_token();
if(cur_tok!=end_write_token){

const char*hlp[]= {
"On this page there's a \\write with fewer real {'s than }'s.",
"I can't handle that very well; good luck.",NULL
};
tex_error("Unbalanced write command",hlp);
do{
get_token();
}while(cur_tok!=end_write_token);
}
mode= old_mode;
end_token_list();
}
コード例 #2
0
ファイル: mathlist.c プロジェクト: syntheticpp/cpptex
void tex::start_eq_no ()
	{
	saved(0) = cur_chr;
	incr(save_ptr);
	push_math(MATH_SHIFT_GROUP);
	reg_define(int_reg[CUR_FAM_CODE], INT_REG, -1);
	if (every_math != null)
		begin_token_list(every_math, EVERY_MATH_TEXT);
	}
コード例 #3
0
ファイル: boxlist.c プロジェクト: syntheticpp/cpptex
void tex::new_graf(bool indented)
	{
	prev_graf = 0;
	if (mode == VMODE || head != tail)
		tail_append(new_param_glue(PAR_SKIP_CODE));
	lhmin = norm_min(left_hyphen_min);
	rhmin = norm_min(right_hyphen_min);
	push_nest();
	mode = HMODE;
	space_factor = 1000;
	clang = 0;	
	if (indented) {
		link(head) = tail = new_null_box();
		box_width(tail) = par_indent;
	}
	if (every_par != null)
		begin_token_list(every_par, EVERY_PAR_TEXT);
	if (nest_ptr == nest + 1) 
		build_page();
}
コード例 #4
0
ファイル: page.c プロジェクト: syntheticpp/cpptex
void tex::fire_up(ptr c)
	{
	int	n;
	bool	wait;
	ptr	prev_p;
	scal	save_vfuzz;
	int	save_vbadness;
	ptr	save_split_top_skip;
	ptr	p, q, r;

	if (type(best_page_break) == PENALTY_NODE) {
		set_output_penalty(penalty(best_page_break));
		penalty(best_page_break) = INF_PENALTY;
	} else {
		set_output_penalty(INF_PENALTY);
	}
	if (bot_mark != null) {
		if (top_mark != null)
			delete_token_ref(top_mark);
		top_mark = bot_mark;
		add_token_ref(top_mark);
		delete_token_ref(first_mark);
		first_mark = null;
	}
	if (c == best_page_break) {
		best_page_break = null;
	}
	if (box(255) != null) {
		print_err(null_str);
		print_esc("box");
		print("255 is not void");
		help_box_255();
		box_error(255);
	}
	insert_penalties = 0;
	save_split_top_skip = split_top_skip;
	if (holding_inserts <= 0) {
		r = link(page_ins_head);
		while (r != page_ins_head) {
			if (best_ins_ptr(r) != null) {
				n = subtype(r);
				ensure_vbox(n);
				if (box(n) == null)
					box(n) = new_null_box();
				p = node_list(box(n));
				while (link(p) != null) {
					p = link(p);
				}
				last_ins_ptr(r) = p;
			}
			r = link(r);
		}
	}
	q = hold_head;
	link(q) = null;
	prev_p = page_head;
	p = link(prev_p);
	while (p != best_page_break) {
		if (type(p) == INS_NODE) {
			if (holding_inserts <= 0) {
				wait = insert_box(p);
				link(prev_p) = link(p);
				link(p) = null;
				if (wait) {
					q = link(q) = p;
					incr(insert_penalties);
				} else {
					delete_glue_ref(split_top_ptr(p));
					free_node(p, INS_NODE_SIZE);
				}
				p = prev_p;
			}
		} else if (type(p) == MARK_NODE) {
			if (first_mark == null) {
				first_mark = mark_ptr(p);
				add_token_ref(first_mark);
			}
			if (bot_mark != null)
				delete_token_ref(bot_mark);
			bot_mark = mark_ptr(p);
			add_token_ref(bot_mark);
		}
		prev_p = p;
		p = link(prev_p);
	}
	split_top_skip = save_split_top_skip;
	if (p != null) {
		if (link(contrib_head) == null) {
			if (nest_ptr == nest) {
				tail = page_tail;
			} else {
				contrib_tail = page_tail;
			}
		}
		link(page_tail) = link(contrib_head);
		link(contrib_head) = p;
		link(prev_p) = null;
	}
	save_vbadness = vbadness;
	save_vfuzz = vfuzz;
	vbadness = INF_BAD;
	vfuzz = MAX_DIMEN;
	box(255) = vpackage(link(page_head),
		best_size, EXACTLY, page_max_depth);
	vbadness = save_vbadness;
	vfuzz = save_vfuzz;
	if (last_glue != null)
		delete_glue_ref(last_glue);
	start_new_page();
	if (q != hold_head) {
		link(page_head) = link(hold_head);
		page_tail = q;
	}
	r = link(page_ins_head);
	while (r != page_ins_head) {
		q = link(r);
		free_node(r, PAGE_INS_NODE_SIZE);
		r = q;
	}
	link(page_ins_head) = page_ins_head;
	if (top_mark != null && first_mark == null) {
		first_mark = top_mark;
		add_token_ref(top_mark);
	}
	if (output_routine != null) {
		if (dead_cycles >= max_dead_cycles) {
			print_err("Output loop---");
			print_int(dead_cycles);
			print(" consecutive dead cycles");
			help_dead_cycles();
			error();
		} else {
			output_active = TRUE;
			incr(dead_cycles);
			push_nest();
			mode = -VMODE;
			prev_depth = IGNORE_DEPTH;
			mode_line = -line;
			begin_token_list(output_routine, OUTPUT_TEXT);
			new_save_level(OUTPUT_GROUP);
			normal_paragraph();
			scan_left_brace();
			return;
		}
	}
	if (link(page_head) != null) {
		if (link(contrib_head) == null) {
			if (nest_ptr == nest) {
				tail = page_tail;
			} else {
				contrib_tail = page_tail;
			}
		} else {
			link(page_tail) = link(contrib_head);
		}
		link(contrib_head) = link(page_head);
		link(page_head) = null;
		page_tail = page_head;
	}
	ship_out(box(255));
	box(255) = null;
}
コード例 #5
0
ファイル: lnewtokenlib.c プロジェクト: live-clones/luatex
inline static int run_put_next(lua_State * L)
{
    int n = lua_gettop(L);
    int m = 0;
    int i = 0;
    halfword h = null;
    halfword t = null;
    halfword x = null;
    lua_token *p ;
    if (n == 0) {
        /* we accept a single nil argument */
        return 0;
    }
    lua_get_metatablelua(luatex_token);
    m = lua_gettop(L);
    if (lua_type(L,1) == LUA_TTABLE) {
        if (n>1) {
            normal_error("token lib","only one table permitted in put_next");
        } else {
            for (i = 1;; i++) {
                lua_rawgeti(L, 1, i); /* table mt token */
                if (lua_type(L,-1) == LUA_TNIL) {
                    break;
                } else {
                    p = lua_touserdata(L, -1);
                    if (p == NULL) {
                        normal_error("token lib","lua <token> expected in put_next (1)");
                    } else if (!lua_getmetatable(L, -1)) { /* table mt token mt */
                        normal_error("token lib","lua <token> expected in put_next (2)");
                    } else if (!lua_rawequal(L, m, -1)) {
                        normal_error("token lib","lua <token> expected in put_next (3)");
                    } else {
                        fast_get_avail(x) ;
                        token_info(x) = token_info(p->token);
                        if (h == null) {
                            h = x;
                        } else {
                            token_link(t) = x;
                        }
                        t = x;
                    }
                    lua_pop(L, 1);
                }
            }
        }
    } else {
        for (i = 1; i <= n; i++) {
            p = lua_touserdata(L,i);
            if (p == NULL) {
                normal_error("token lib","lua <token> expected in put_next (4)");
            } else if (!lua_getmetatable(L, i)) { /* table mt token mt */
                normal_error("token lib","lua <token> expected in put_next (5)");
            } else if (!lua_rawequal(L, m, -1)) {
                normal_error("token lib","lua <token> expected in put_next (6)");
            } else {
                fast_get_avail(x) ;
                token_info(x) = token_info(p->token);
                if (h == null) {
                    h = x;
                } else {
                    token_link(t) = x;
                }
                t = x;
            }
            lua_pop(L, 1);
        }
    }
    if (h == null) {
        /* can't happen */
    } else {
        begin_token_list(h,0);
    }
    lua_settop(L,n);
    return 0;
}
コード例 #6
0
ファイル: boxlist.c プロジェクト: syntheticpp/cpptex
void tex::begin_box(int box_context)
	{
	int	k, m, n;
	ptr	p=0, q;

	switch (cur_chr)
	{
	case BOX_CODE:
		scan_eight_bit_int();
		cur_box = box(cur_val);
		box(cur_val) = null;
		break;
	
	case COPY_CODE:
		scan_eight_bit_int();
		cur_box = copy_node_list(box(cur_val));
		break;
	
	case LAST_BOX_CODE:
		cur_box = null;
		if (abs(mode) == MMODE) {
			you_cant();
			help_lastbox_m();
			error();
		} else if (mode == VMODE && head == tail) {
			you_cant();
			help_lastbox_v();
			error();
		} else if (type(tail) == HLIST_NODE
			|| type(tail) == VLIST_NODE) {
			for (q = head; q != tail; q = link(p)) {
				p = q;
				if (type(q) == DISC_NODE) {
					m = 1;
					while (m <= replace_count(q)) {
						p = link(p);
						incr(m);
					}
					if (p == tail) {
						break;
					}
				}
			}
			cur_box = tail;
			shift_amount(cur_box) = 0;
			tail = p;
			link(p) = null;
		}
		break;

	case VSPLIT_CODE:
		scan_eight_bit_int();
		n = cur_val;
		if (!scan_keyword("to")) {
			print_err("Missing `to' inserted");
			help_vsplit();
			error();
		}
		scan_normal_dimen();
		cur_box = vsplit(n, cur_val);
		break;
	
	default:
		k = cur_chr - VTOP_CODE;
		saved(0) = box_context;
		if (k == HMODE) {
			if (box_context < BOX_FLAG && abs(mode) == VMODE) {
				scan_spec(ADJUSTED_HBOX_GROUP, TRUE);
			} else {
				scan_spec(HBOX_GROUP, TRUE);
			}
		} else {
			if (k == VMODE) {
				scan_spec(VBOX_GROUP, TRUE);
			} else {
				scan_spec(VTOP_GROUP, TRUE);
				k = VMODE;
			}
			normal_paragraph();
		}
		push_nest();
		mode = -k;
		if (k == VMODE) {
			prev_depth = IGNORE_DEPTH;
			if (every_vbox != null)
				begin_token_list(every_vbox, EVERY_VBOX_TEXT);
		} else {
			space_factor = 1000;
			if (every_hbox != null) 
				begin_token_list(every_hbox, EVERY_HBOX_TEXT);
		}
		return;
	}
	box_end(box_context);
}
コード例 #7
0
ファイル: mathlist.c プロジェクト: syntheticpp/cpptex
void tex::init_math ()
	{
	fnt	f;
	int	m, n;
	ptr	p, q;
	scal	d, l, s, v, w;

	get_token();
	if (cur_cmd == MATH_SHIFT && mode > 0) {
		if (head == tail) {
			pop_nest();
			w = -MAX_DIMEN;
		} else {
			line_break(display_widow_penalty);
			v = shift_amount(just_box) + 2 * quad(cur_font);
			w = -MAX_DIMEN;
			p = list_ptr(just_box);
			while (p != null) {
		reswitch:
				if (is_char_node(p)) {
					f = font(p);
					d = char_width(f,
						char_info(f, character(p)));
					goto found;
				}
				switch (type(p))
				{
				case HLIST_NODE:
				case VLIST_NODE:
				case RULE_NODE:
					d = box_width(p);
					goto found;
				
				case LIGATURE_NODE:
					p = make_char_from_lig(p);
					goto reswitch;
				
				case KERN_NODE:
					d = kern_width(p);
					break;

				case MATH_NODE:
					d = box_width(p);
					break;

				case GLUE_NODE:
					q = glue_ptr(p);
					d = box_width(q);
					if (glue_sign(just_box) ==
						STRETCHING) {
						if (glue_order(just_box) ==
							stretch_order(q)
						&& stretch(q) != 0)
							v = MAX_DIMEN;
					} else if (glue_sign(just_box) ==
						SHRINKING)  {
						if (glue_order(just_box) ==
							shrink_order(q)
						&& shrink(q) != 0) 
							v = MAX_DIMEN;
					}
					if (subtype(p) >= A_LEADERS)	
						goto found;
					break;

				case WHATSIT_NODE: 
					d = 0;
					break;

				default:
					d = 0;
					break;
				}
				if (v < MAX_DIMEN)
					v += d;
				goto not_found;
			
			found:
				if (v < MAX_DIMEN) {
					v += d;
					w = v;
				} else {
					w = MAX_DIMEN;
					break;
				}

			not_found:
				p = link(p);
			}
		}
		if (par_shape_ptr == null) {
			if (hang_indent != 0
			&& (hang_after >= 0
				&& prev_graf + 2 > hang_after
					|| prev_graf + 1 < -hang_after)) {
				l = hsize - abs(hang_indent);
				s = (hang_indent > 0) ? hang_indent : 0;
			} else {
				l = hsize;
				s = 0;
			}
		} else {
			n = info(par_shape_ptr);
			if (prev_graf + 2 >= n)
				m = n;
			else m = prev_graf + 2;
			l = par_shape_width(m);
			s = par_shape_indent(m);
		}
		push_math(MATH_SHIFT_GROUP);
		mode = MMODE;
		reg_define(int_reg[CUR_FAM_CODE], INT_REG, -1);
		reg_define(dimen_reg[PRE_DISPLAY_SIZE_CODE], DIMEN_REG, w);
		reg_define(dimen_reg[DISPLAY_WIDTH_CODE], DIMEN_REG, l);
		reg_define(dimen_reg[DISPLAY_INDENT_CODE], DIMEN_REG, s);
		if (every_display != null)
			begin_token_list(every_display, EVERY_DISPLAY_TEXT);
		if (nest_ptr == nest + 1)
			build_page();
	} else {
		back_input(); 
		push_math(MATH_SHIFT_GROUP);
		reg_define(int_reg[CUR_FAM_CODE], INT_REG, -1);
		if (every_math != null)
			begin_token_list(every_math, EVERY_MATH_TEXT);
	}
}
コード例 #8
0
ファイル: eval.c プロジェクト: syntheticpp/cpptex
void tex::main_control()
	{
	if (every_job != null)
		begin_token_list(every_job, EVERY_JOB_TEXT);
	
	big_switch:
	get_x_token();

   reswitch:
	if (tracing_commands > 0)
		show_cur_cmd_chr();
	
	switch(abs(mode) + cur_cmd) {
		hmode(LETTER):
		hmode(OTHER_CHAR):
		hmode(CHAR_GIVEN):
			goto main_loop;
		
		hmode(CHAR_NUM):
			scan_char_num();
		   cur_chr = cur_val;
		   goto main_loop;
		
		hmode(NO_BOUNDARY):
			get_x_token();
		   if (cur_cmd == LETTER || cur_cmd == OTHER_CHAR
				 || cur_cmd == CHAR_GIVEN || cur_cmd == CHAR_NUM) {
				cancel_boundary = TRUE;
				}
			goto reswitch;

		hmode(SPACER):
			if (space_factor == 1000) {
				goto append_normal_space;
				} 
			else {
				app_space();
				}
		   break;
	
	hmode(EX_SPACE):
	mmode(EX_SPACE):
		goto append_normal_space;
	
	any_mode(RELAX):
	vmode(SPACER):
	mmode(SPACER):
	mmode(NO_BOUNDARY):
		break;
	
	any_mode(IGNORE_SPACES):
		get_nbx_token();
		goto reswitch;

	vmode(STOP):
		if (its_all_over())
			return;
		break;

	any_mode(LAST_ITEM):
	any_mode(MAC_PARAM):
	non_math(EQ_NO):
	vmode(VMOVE):
	hmode(HMOVE):
	mmode(HMOVE):
	vmode(VADJUST):
	vmode(ITAL_CORR):
		report_illegal_case();
		break;

	non_math(SUP_MARK):
	non_math(SUB_MARK):
	non_math(MATH_CHAR_NUM):
	non_math(MATH_GIVEN):
	non_math(MATH_COMP):
	non_math(DELIM_NUM):
	non_math(LEFT_RIGHT):
	non_math(ABOVE):
	non_math(RADICAL):
	non_math(MATH_STYLE):
	non_math(MATH_CHOICE):
	non_math(VCENTER):
	non_math(NON_SCRIPT):
	non_math(MKERN):
	non_math(LIMIT_SWITCH):
	non_math(MSKIP):
	non_math(MATH_ACCENT):
	mmode(ENDV):
	mmode(PAR_END):
	mmode(STOP):
	mmode(VSKIP):
	mmode(UN_VBOX):
	mmode(VALIGN):
	mmode(HRULE):
		insert_dollar_sign();
		break;
	
	vmode(HRULE):
	hmode(VRULE):
	mmode(VRULE):
		tail_append(scan_rule_spec());
		if (abs(mode) == VMODE)
			prev_depth = IGNORE_DEPTH;
		else if (abs(mode) == HMODE)
			space_factor = 1000;
		break;
	
	vmode(VSKIP):
	hmode(HSKIP):
	mmode(HSKIP):
	mmode(MSKIP):
		append_glue();
		break;
	
	any_mode(KERN):
	mmode(MKERN):
		append_kern();
		break;
	
	non_math(LEFT_BRACE):
		new_save_level(SIMPLE_GROUP);
		break;

	any_mode(BEGIN_GROUP):
		new_save_level(SEMI_SIMPLE_GROUP);
		break;

	any_mode(END_GROUP):
		if (cur_group == SEMI_SIMPLE_GROUP) {
			unsave();
		} else {
			off_save();
		}
		break;
	
	any_mode(RIGHT_BRACE):
		handle_right_brace();
		break;

	vmode(HMOVE):
	hmode(VMOVE):
	mmode(VMOVE): {
		int	t;

		t = cur_chr;
		scan_normal_dimen();
		if (t == 0) {
			scan_box(cur_val);
		} else {
			scan_box(-cur_val);
		}
		break;
	}
	any_mode(LEADER_SHIP):
		scan_box(LEADER_FLAG + cur_chr - A_LEADERS);
		break;
	
	any_mode(MAKE_BOX):
		begin_box(0);
		break;

	vmode(START_PAR):
		new_graf(cur_chr > 0);
		break;
	
	vmode(LETTER):
	vmode(OTHER_CHAR):
	vmode(CHAR_NUM):
	vmode(CHAR_GIVEN):
	vmode(MATH_SHIFT):
	vmode(UN_HBOX):
	vmode(VRULE):
	vmode(ACCENT):
	vmode(DISCRETIONARY):
	vmode(HSKIP):
	vmode(VALIGN):
	vmode(EX_SPACE):
	vmode(NO_BOUNDARY):
		back_input();
		new_graf(TRUE);
		break;
	
	hmode(START_PAR):
	mmode(START_PAR):
		indent_in_hmode();
		break;
	
	vmode(PAR_END):
		normal_paragraph();
		if (mode > 0)
			build_page();
		break;

	hmode(PAR_END):
		if (align_state < 0)
			off_save();
		end_graf();
		if (mode == VMODE)	
			build_page();
		break;
	
	hmode(STOP):
	hmode(VSKIP):
	hmode(HRULE):
	hmode(UN_VBOX):
	hmode(HALIGN):
		head_for_vmode();
		break;
	
	any_mode(INSERT):
	hmode(VADJUST):
	mmode(VADJUST):
		begin_insert_or_adjust();
		break;
	
	any_mode(MARK):
		make_mark();
		break;
	
	any_mode(BREAK_PENALTY):
		append_penalty();
		break;
	
	any_mode(REMOVE_ITEM):
		delete_last();
		break;
	
	vmode(UN_VBOX):
	hmode(UN_HBOX):
	mmode(UN_HBOX):
		unpackage();
		break;
	
	hmode(ITAL_CORR):
		append_italic_correction();
		break;
	
	mmode(ITAL_CORR):
		tail_append(new_kern(0));
		break;

	hmode(DISCRETIONARY):
	mmode(DISCRETIONARY):
		append_discretionary();
		break;
	
	hmode(ACCENT):
		make_accent();
		break;
	
	any_mode(CAR_RET):
	any_mode(TAB_MARK):
		align_error();
		break;

	any_mode(NO_ALIGN):
		no_align_error();
		break;
	
	any_mode(OMIT):
		omit_error();
		break;

	vmode(HALIGN):
	hmode(VALIGN):
		init_align();
		break;
	
	mmode(HALIGN):
		if (privileged()) {
			if (cur_group == MATH_SHIFT_GROUP) {
				init_align();
			} else {
				off_save();
			}
		}
		break;

	vmode(ENDV):
	hmode(ENDV):
		do_endv();
		break;
	
	any_mode(END_CS_NAME):
		cs_error();
		break;

	hmode(MATH_SHIFT):
		init_math();
		break;
	
	mmode(EQ_NO):
		if (privileged()) {
			if (cur_group == MATH_SHIFT_GROUP) {
				start_eq_no();
			} else {
				off_save();
			}
		}
		break;
	
	mmode(LEFT_BRACE):
		tail_append(new_noad());
		back_input();
		scan_math(nucleus(tail));
		break;

	mmode(LETTER):
	mmode(OTHER_CHAR):
	mmode(CHAR_GIVEN):
		if (cur_chr < 256)
			set_math_char(math_code(cur_chr));
		else set_math_char(cur_chr);
		break;
	
	mmode(CHAR_NUM):
		scan_char_num();
		cur_chr = cur_val;
		if (cur_chr < 256)
			set_math_char(math_code(cur_chr));
		else set_math_char(cur_chr);
		break;
	
	mmode(MATH_CHAR_NUM):
		scan_fifteen_bit_int();
		set_math_char(cur_val);
		break;
	
	mmode(MATH_GIVEN):
		set_math_char(cur_chr);
		break;

	mmode(DELIM_NUM):
		scan_twenty_seven_bit_int();
		set_math_char(cur_val / 010000);
		break;
	
	mmode(MATH_COMP):
		tail_append(new_noad());
		type(tail) = cur_chr;
		scan_math(nucleus(tail));
		break;
	
	mmode(LIMIT_SWITCH):
		math_limit_switch();
		break;

	mmode(RADICAL):
		math_radical();
		break;

	mmode(ACCENT):
	mmode(MATH_ACCENT):
		math_ac();
		break;

	mmode(VCENTER):
		scan_spec(VCENTER_GROUP, FALSE);
		normal_paragraph();
		push_nest();
		mode = -VMODE;
		prev_depth = IGNORE_DEPTH;
		if (every_vbox != null)
			begin_token_list(every_vbox, EVERY_VBOX_TEXT);
		break;
	
	mmode(MATH_STYLE):
		tail_append(new_style(cur_chr));
		break;
	
	mmode(NON_SCRIPT):
		tail_append(new_glue(zero_glue));
		subtype(tail) = COND_MATH_GLUE;
		break;
	
	mmode(MATH_CHOICE):
		append_choices();
		break;

	mmode(SUB_MARK):
	mmode(SUP_MARK):
		sub_sup();
		break;
	
	mmode(ABOVE):
		math_fraction();
		break;
	
	mmode(LEFT_RIGHT):
		math_left_right();
		break;

	mmode(MATH_SHIFT):
		if (cur_group == MATH_SHIFT_GROUP) {
			after_math();
		} else {
			off_save();
		}
		break;

	any_mode(AFTER_ASSIGNMENT):
		get_token();
		after_token = cur_tok;
		break;
	
	any_mode(AFTER_GROUP):
		get_token();
		save_for_after(cur_tok);
		break;

	any_mode(IN_STREAM):
		clopen_stream();
		break;

	any_mode(MESSAGE):
		issue_message();
		break;
	
	any_mode(CASE_SHIFT):
		shift_case();
		break;
	
	any_mode(XRAY):
		show_whatever();
		break;
	
	any_mode(EXTENSION):
		do_extension();
		break;
	
	default:
		prefixed_command();
		break;
	}
	goto big_switch;

#define adjust_space_factor() \
{ \
	main_s = sf_code(cur_chr); \
	if (main_s == 1000) { \
		space_factor = 1000; \
	} else if (main_s < 1000) { \
		if (main_s > 0) { \
			space_factor = main_s; \
		} \
	} else if (space_factor < 1000) { \
		space_factor = 1000; \
	} else { \
		space_factor = main_s; \
	} \
}
		
main_loop:
	adjust_space_factor();
	main_f = cur_font;
	bchar = font_bchar(main_f);
	false_bchar = font_false_bchar(main_f);
	if (mode > 0 && language != clang)
		fix_language();
	fast_new_avail(lig_stack);
	font(lig_stack) = main_f;
	character(lig_stack) = cur_l = cur_chr;
	cur_q = tail;
	if (cancel_boundary) {
		cancel_boundary = FALSE;
		main_k = NON_ADDRESS;
	} else {
		main_k = bchar_label(main_f);
	}
	if (main_k == NON_ADDRESS)
		goto main_loop_move_2;
	cur_r = cur_l;
	cur_l = NON_CHAR;
	goto main_lig_loop_1;

#define pack_lig(RT_HIT) \
{ \
	main_p = new_ligature(main_f, cur_l, link(cur_q)); \
	if (lft_hit) { \
		subtype(main_p) = 2; \
		lft_hit = FALSE; \
	} \
	if (RT_HIT && lig_stack == null) { \
		incr(subtype(main_p)); \
		rt_hit = FALSE; \
	} \
	tail = link(cur_q) = main_p; \
	ligature_present = FALSE; \
}

#define wrapup(RT_HIT) \
{ \
	if (cur_l < NON_CHAR) { \
		if (character(tail) == hyphen_char(main_f) \
		&& link(cur_q) != null) \
			ins_disc = TRUE; \
		if (ligature_present) \
			pack_lig(RT_HIT); \
		if (ins_disc) { \
			ins_disc = FALSE; \
			if (mode > 0) \
				tail_append(new_disc()); \
		} \
	} \
}

main_loop_wrapup:
	wrapup(rt_hit);

main_loop_move:
	if (lig_stack == null)
		goto reswitch;
	cur_q = tail;
	cur_l = cur_r;

main_loop_move_1:
	if (!is_char_node(lig_stack))
		goto main_loop_move_lig;

main_loop_move_2:
	if (cur_chr < font_bc(main_f) || cur_chr > font_ec(main_f)) {
		char_warning(main_f, cur_chr);
		free_avail(lig_stack);
		goto big_switch;
	}
	main_i = char_info(main_f, cur_l);
	if (!char_exists(main_i)) {
		char_warning(main_f, cur_chr);
		free_avail(lig_stack);
		goto big_switch;
	}
	tail_append(lig_stack);

main_loop_lookahead:
	get_next();
	if (cur_cmd == LETTER
	|| cur_cmd == OTHER_CHAR
	|| cur_cmd == CHAR_GIVEN) {
		goto main_loop_lookahead_1;
	}
	x_token();
	if (cur_cmd == LETTER
	|| cur_cmd == OTHER_CHAR
	|| cur_cmd == CHAR_GIVEN) {
		goto main_loop_lookahead_1;
	}
	if (cur_cmd == CHAR_NUM) {
		scan_char_num();
		cur_chr = cur_val;
		goto main_loop_lookahead_1;
	}
	if (cur_cmd == NO_BOUNDARY) {
		bchar = NON_CHAR;
	}
	cur_r = bchar;
	lig_stack = null;
	goto main_lig_loop;

main_loop_lookahead_1:
	adjust_space_factor();
	fast_new_avail(lig_stack);
	font(lig_stack) = main_f;
	character(lig_stack) = cur_r = cur_chr;
	if (cur_r == false_bchar) {
		cur_r = NON_CHAR;
	}

main_lig_loop:
	if (char_tag(main_i) != LIG_TAG) {
		goto main_loop_wrapup;
	}
	main_k = lig_kern_start(main_f, main_i);
	main_j = *main_k;
	if (skip_byte(main_j) <= STOP_FLAG) {
		goto main_lig_loop_2;
	}
	main_k = lig_kern_restart(main_f, main_j);

main_lig_loop_1:
	main_j = *main_k;

main_lig_loop_2:
	if (next_char(main_j) == cur_r
	&& skip_byte(main_j) <= STOP_FLAG) {
		if (op_byte(main_j) >= KERN_FLAG) {
			wrapup(rt_hit);
			tail_append(new_kern(char_kern(main_f, main_j)));
			goto main_loop_move;
		}
		if (cur_l == NON_CHAR) {
			lft_hit = TRUE;
		} else if (lig_stack == null) {
			rt_hit = TRUE;
		}
		if(interrupted) throw std::logic_error("interrupted");
		switch (op_byte(main_j))
		{
		case 1: case 5:
			cur_l = rem_byte(main_j);
			main_i = char_info(main_f, cur_l);
			ligature_present = TRUE;
			break;
			
		case 2: case 6:
			cur_r = rem_byte(main_j);
			if (lig_stack == null) {
				lig_stack = new_lig_item(cur_r);
				bchar = NON_CHAR;
			} else if (is_char_node(lig_stack)) {
				main_p = lig_stack;
				lig_stack = new_lig_item(cur_r);
				lig_ptr(lig_stack) = main_p;
			} else {
				character(lig_stack) = cur_r;
			}
			break;

		case 3:
			cur_r = rem_byte(main_j);
			main_p = lig_stack;
			lig_stack = new_lig_item(cur_r);
			link(lig_stack) = main_p;
			break;

		case 7: case 11:
			wrapup(FALSE);
			cur_q = tail;
			cur_l = rem_byte(main_j);
			main_i = char_info(main_f, cur_l);
			ligature_present = TRUE;
			break;

		default:
			cur_l = rem_byte(main_j);
			ligature_present = TRUE;
			if (lig_stack == null) {
				goto main_loop_wrapup;
			} else {
				goto main_loop_move_1;
			}
			break;
		}
		if (op_byte(main_j) > 4 && op_byte(main_j) != 7)
			goto main_loop_wrapup;
		if (cur_l < NON_CHAR)
			goto main_lig_loop;
		main_k = bchar_label(main_f);
		goto main_lig_loop_1;
	}
	if (skip_byte(main_j) == 0) {
		incr(main_k);
	} else {
		if (skip_byte(main_j) >= STOP_FLAG)
			goto main_loop_wrapup;
		main_k += skip_byte(main_j) + 1;
	}
	goto main_lig_loop_1;

main_loop_move_lig:
	main_p = lig_ptr(lig_stack);
	if (main_p != null) {
		tail_append(main_p);
	}
	main_t = lig_stack;
	lig_stack = link(main_t);
	free_node(main_t, SMALL_NODE_SIZE);
	main_i = char_info(main_f, cur_l);
	ligature_present = TRUE;
	if (lig_stack == null) {
		if (main_p != null) {
			goto main_loop_lookahead;
		} else {
			cur_r = bchar;
		}
	} else {
		cur_r = character(lig_stack);
	}
	goto main_lig_loop;

append_normal_space:
	if (space_skip == zero_glue) {
		main_p = font_glue(cur_font);
		if (main_p == null)
			main_p = find_font_glue(cur_font);
		main_t = new_glue(main_p);
	} else {
		main_t = new_param_glue(SPACE_SKIP_CODE);
	}
	tail_append(main_t);
	goto big_switch;
}