Example #1
0
void pretty_print(const struct colors *colors, const struct BFTW *ftwbuf) {
	const char *path = ftwbuf->path;

	if (!colors) {
		puts(path);
		return;
	}

	const char *filename = path + ftwbuf->nameoff;

	if (colors->dir) {
		print_esc(colors->dir, stdout);
	}
	fwrite(path, 1, ftwbuf->nameoff, stdout);
	if (colors->dir) {
		print_esc(colors->reset, stdout);
	}

	const char *color = file_color(colors, filename, ftwbuf->statbuf);
	if (color) {
		print_esc(color, stdout);
	}
	fputs(filename, stdout);
	if (color) {
		print_esc(colors->reset, stdout);
	}
	fputs("\n", stdout);
}
Example #2
0
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));
}
Example #3
0
static void pretty_format(const struct colors *colors, const char *color, const char *format, va_list args) {
	if (color) {
		print_esc(color, stderr);
	}

	vfprintf(stderr, format, args);

	if (color) {
		print_esc(colors->reset, stderr);
	}
}
Example #4
0
void tex::extra_right_brace ()
	{
	print_err("Extra }, or forgotten ");
	switch (cur_group) {
		case SEMI_SIMPLE_GROUP: print_esc("endgroup"); break;
		case MATH_SHIFT_GROUP: print("$"); break;
		case MATH_LEFT_GROUP: print_esc("right"); break;
		}
	help_group_close();
	error();
	incr(align_state);
	}
Example #5
0
void tex::show_kern(ptr p)
	{
	if (subtype(p) != MU_GLUE) {
		print_esc("kern");
		if (subtype(p) != NORMAL)
			print(" ");
		print_scaled(kern_width(p));
		if (subtype(p) == ACC_KERN)
			print(" (for accent)");
	} else {
		print_esc("mkern");
		print_scaled(kern_width(p));
		print("mu");
	}
	}
Example #6
0
void tex::math_left_right ()
	{
	ptr	p;
	int	t;
	mcell	garbage;

	t = cur_chr;
	if (t == RIGHT_NOAD && cur_group != MATH_LEFT_GROUP) {
		if (cur_group == MATH_SHIFT_GROUP) {
			scan_delimiter((ptr)&garbage, FALSE);
			print_err("Extra ");
			print_esc("right");
			help_xtra_right();
			error();
		} else {
			off_save();
		}
	} else {
		p = new_noad();
		type(p) = t;
		scan_delimiter(delimiter(p), FALSE);
		if (t == LEFT_NOAD) {
			push_math(MATH_LEFT_GROUP);
			tail = link(head) = p;
		} else {
			p = fin_mlist(p);
			unsave();
			tail_append(new_noad());
			type(tail) = INNER_NOAD;
			math_type(nucleus(tail)) = SUB_MLIST;
			math_link(nucleus(tail)) = p;
		}
	}
}
Example #7
0
void tex::omit_error ()
	{
	print_err("Misplaced ");
	print_esc("omit");
	help_omit();
	error();
	}
Example #8
0
/// Print string STR, evaluating \ escapes.
void builtin_printf_state_t::print_esc_string(const wchar_t *str) {
    for (; *str; str++)
        if (*str == L'\\')
            str += print_esc(str, true);
        else
            this->append_output(*str);
}
Example #9
0
void tex::cs_error ()
	{
	print_err("Extra ");
	print_esc("endcsname");
	help_csname();
	error();
	}
Example #10
0
void tex::no_align_error ()
	{
	print_err("Misplaced ");
	print_esc("noalign");
	help_noalign();
	error();
	}
Example #11
0
void print_cs(int p)
{
str_number t= cs_text(p);
if(p<hash_base){

if(p==null_cs){
tprint_esc("csname");
tprint_esc("endcsname");
print_char(' ');
}else{
tprint_esc("IMPOSSIBLE.");
}
}else if((p>=undefined_control_sequence)&&
((p<=eqtb_size)||p> eqtb_size+hash_extra)){
tprint_esc("IMPOSSIBLE.");
}else if(t>=str_ptr){
tprint_esc("NONEXISTENT.");
}else{
if(is_active_cs(t)){
print(active_cs_value(t));
}else{
print_esc(t);
if(single_letter(t)){
if(get_cat_code(cat_code_table_par,pool_to_unichar(str_string(t)))==letter_cmd)
print_char(' ');
}else{
print_char(' ');
}
}
}
}
Example #12
0
void tex::begin_insert_or_adjust ()
	{
	if (cur_cmd == VADJUST) {
		cur_val = 255;
		} 
	else {
		scan_eight_bit_int();
		if (cur_val == 255) {
			print_err("You can't ");
			print_esc("insert");
			print_int(255);
			help_insert_255();
			error();
			cur_val = 0;
			}
		}
	saved(0) = cur_val;
	incr(save_ptr);
	new_save_level(INSERT_GROUP);
	scan_left_brace();
	normal_paragraph();
	push_nest();
	mode = -VMODE;
	prev_depth = IGNORE_DEPTH;
	}
Example #13
0
void tex::math_ac ()
	{
	if (cur_cmd == ACCENT) {
		print_err("Please use ");
		print_esc("mathaccent");
		print(" for accents in math mode");
		help_math_accent();
		error();
	}
	tail_append(new_node(ACCENT_NOAD_SIZE));
	type(tail) = ACCENT_NOAD;
	subtype(tail) = NORMAL;
	mzero(nucleus(tail));
	mzero(subscr(tail));
	mzero(supscr(tail));
	math_type(accent_chr(tail)) = MATH_CHAR;
	scan_fifteen_bit_int();
	character(accent_chr(tail)) = cur_val % 256;
	if (cur_val >= VAR_CODE && fam_in_range()) {
		fam(accent_chr(tail)) = cur_fam;
	} else {
		fam(accent_chr(tail)) = cur_val / 256 % 16;
	}
	scan_math(nucleus(tail));
	}
Example #14
0
void main(int argc, char **argv)
{
  int i, k, quit;
	
	quit = 0;

  /* nothing has gotten through okay yet */	
  for (i = START_AT; i < STOP_AT; i++)
	{
		valid[i] = 0;
		skip[i] = 0;
	}

  skipchars(argv+1);

	terminal_save(0);
	terminal_raw(0);

  setbuf(stdout,NULL);
	
  handshake();

  /* test all the chars */
  for (i = START_AT; i < STOP_AT; i++ )
  {
		/* don't send chars we are told to skip */
    if ( skip[i] )
      continue;
		
    fprintf(stderr, "%3d sending char\n", i);

    /* attempt to send this char across, in a cute little packet */
		for (k=0; k<TRIES; k++)
		{
			if ( !skip[(int)XON] )
				printf("\n%d %c%c%c%c%c\n", i, START, (char)i, STOP, XON, END_PACKET );
			else
				printf("\n%d %c%c%c%c\n", i, START, (char)i, STOP, END_PACKET );
			
			bum(NULL);

 			/* while we're at it, take a look to the other side */
			if (!quit)
				quit = handle_incoming();
		}
	}

  bum(QUIT);

  /* let the other side finish */
	while (!quit)
		quit = handle_incoming();
	
  print_esc();
	
	terminal_restore(0);
}
Example #15
0
void tex::show_rule(ptr p)
	{
	print_esc("rule(");
	print_rule_dimen(rule_height(p));
	print("+");
	print_rule_dimen(rule_depth(p));
	print(")x");
	print_rule_dimen(rule_width(p));
	}
Example #16
0
void tex::show_glue_type(int n)
	{
	print("(");
	if (n < COND_MATH_GLUE) {
		if (n <= GLUE_PARS) {
			print_skip_param(n - 1);
			} 
		else {
			print_mu_skip_param(n - 1 - GLUE_PARS);
			}
		} 
	else if (n == COND_MATH_GLUE) {
		print_esc("nonscript");
		} 
	else {
		print_esc("mskip");
		}
	print(")");
	}
Example #17
0
void tex::show_leaders(ptr p)
	{
	print_esc(null_str);
	if (tex::subtype(p) == C_LEADERS)
		print("c");
	else if (tex::subtype(p) == X_LEADERS)
		print("x");
	print("leaders ");
	print_spec(glue_ptr(p), null_str);
	node_list_display(leader_ptr(p));
}
Example #18
0
void tex::show_discretionary(ptr p)
	{
	print_esc("discretionary");
	if (replace_count(p) > 0) {
		print(" replacing ");
		print_int(replace_count(p));
	}
	node_list_display(pre_break(p));
	append_char('|');
	show_node_list(post_break(p));
	flush_char();
	}
Example #19
0
void tex::show_math(ptr p)
	{
	print_esc("math");
	if (subtype(p) == BEFORE) {
		print("on");
	} else {
		print("off");
	}
	if (math_width(p) != 0) {
		print(", surrounded ");
		print_scaled(math_width(p));
	}
	}
Example #20
0
void sprint_cs(pointer p)
{
str_number t;
if(p==null_cs){
tprint_esc("csname");
tprint_esc("endcsname");
}else{
t= cs_text(p);
if(is_active_cs(t))
print(active_cs_value(t));
else
print_esc(t);
}
}
Example #21
0
void tex::show_insertion(ptr p)
	{
	print_esc("insert");
	print_int(tex::subtype(p));
	print(", natural size ");
	print_scaled(ins_height(p));
	print("; split(");
	print_spec(split_top_ptr(p), null_str);
	print(",");
	print_scaled(ins_depth(p));
	print("); float cost ");
	print_int(float_cost(p));
	node_list_display(ins_ptr(p));
	}
Example #22
0
void tex::show_box1(ptr p)
	{
	if (tex::type(p) == HLIST_NODE)
		print_esc("h");
	else if (tex::type(p) == VLIST_NODE)
		print_esc("v");
	else print_esc("unset");
	print("box(");
	print_scaled(box_height(p));
	print("+")	;
	print_scaled(box_depth(p));
	print(")x")	;
	print_scaled(box_width(p));
	if (tex::type(p) == UNSET_NODE) {
		if (unset_span_count(p) != MIN_QUARTERWORD) {
			print(" (");
			print_int(unset_span_count(p)+1);
			print(" columns)");
		}
		if (unset_stretch(p) != 0) {
			print(", stretch ");
			print_glue(unset_stretch(p), glue_order(p), null_str);
		}
		if (unset_shrink(p) != 0) {
			print(", shrink ");
			print_glue(unset_shrink(p), glue_sign(p), null_str);
		}
	} else {
		show_glue_set(p);
		if (shift_amount(p) != 0) {
			print(", shifted ");
			print_scaled(shift_amount(p));
		}
	}
	node_list_display(list_ptr(p));
}
Example #23
0
void tex::show_glue(ptr p)
	{
	if (tex::subtype(p) >= A_LEADERS) {
		show_leaders(p);
	} else {
		print_esc("glue");
		if (tex::subtype(p) != NORMAL)
			show_glue_type(tex::subtype(p));
		if (tex::subtype(p) != COND_MATH_GLUE) {
			print(" ");
			if (tex::subtype(p) < COND_MATH_GLUE)
				print_spec(glue_ptr(p), null_str);
			else print_spec(glue_ptr(p), "mu");
		}
	}
}
Example #24
0
void tex::show_cur_page()
	{
	ptr	p, q;
	int	t;

	if (page_head == page_tail)
		return;
	print_nl("### current page:");
	if (output_active)
		print(" (held over for next output)");
	show_box(link(page_head));
	if (page_contents > EMPTY) {
		print_nl("total height ");
		print_totals();
		print_nl(" goal height ");
		print_scaled(page_goal);
		p = link(page_ins_head);
		while (p != page_ins_head) {
			print_ln();
			print_esc("insert");
			t = subtype(p);
			print_int(t);
			print(" adds ");
			t = x_over_n(page_ins_height(p), 1000) * count(t);
			print_scaled(t);
			if (type(p) == SPLIT_UP) {
				q = page_head;
				t = 0;
				do {
					q = link(q);
					if (type(q) == INS_NODE
					&& subtype(q) == subtype(p))
						incr(t);
				} while (q != broken_ins(p));
				print(", #");
				print_int(t);
				print(" might split");
			}
			p = link(p);
		}
	}
}
Example #25
0
void tex::head_for_vmode ()
	{
	if (mode < 0) {
		if (cur_cmd != HRULE) {
			off_save();
			} 
		else {
			print_err("You can't use `");
			print_esc("hrule");
			print("' here except with leaders");
			help_head_for_vmode();
			error();
			}
		} 
	else {
		back_input();
		cur_tok = par_tok;
		back_input();
		token_type = INSERTED;
		}
	}
Example #26
0
void print_font_identifier(internal_font_number f)
{
str_number fonttext;
fonttext= font_id_text(f);
if(fonttext> 0){
print_esc(fonttext);
}else{
tprint_esc("FONT");
print_int(f);
}
if(tracing_fonts_par> 0){
tprint(" (");
print_font_name(f);
if(font_size(f)!=font_dsize(f)){
tprint("@");
print_scaled(font_size(f));
tprint("pt");
}
print_char(')');
}
}
int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wchar_t **argv)
{
    int save_argc = argc;		/* Preserve original value.  */
    const wchar_t *f;		/* Pointer into `format'.  */
    const wchar_t *direc_start;	/* Start of % directive.  */
    size_t direc_length;		/* Length of % directive.  */
    bool have_field_width;	/* True if FIELD_WIDTH is valid.  */
    int field_width = 0;		/* Arg to first '*'.  */
    bool have_precision;		/* True if PRECISION is valid.  */
    int precision = 0;		/* Arg to second '*'.  */
    bool ok[UCHAR_MAX + 1] = { };	/* ok['x'] is true if %x is allowed.  */

    for (f = format; *f != L'\0'; ++f)
    {
        switch (*f)
        {
            case L'%':
                direc_start = f++;
                direc_length = 1;
                have_field_width = have_precision = false;
                if (*f == L'%')
                {
                    this->append_output(L'%');
                    break;
                }
                if (*f == L'b')
                {
                    /* FIXME: Field width and precision are not supported
                    for %b, even though POSIX requires it.  */
                    if (argc > 0)
                    {
                        print_esc_string(*argv);
                        ++argv;
                        --argc;
                    }
                    break;
                }

                ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E'] =
                        ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o'] =
                                ok['s'] = ok['u'] = ok['x'] = ok['X'] = true;

                for (;; f++, direc_length++)
                {
                    switch (*f)
                    {
                        case L'I':
                        case L'\'':
                            ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
                                    ok['o'] = ok['s'] = ok['x'] = ok['X'] = false;
                            break;
                        case '-':
                        case '+':
                        case ' ':
                            break;
                        case L'#':
                            ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = false;
                            break;
                        case '0':
                            ok['c'] = ok['s'] = false;
                            break;
                        default:
                            goto no_more_flag_characters;
                    }
                }
no_more_flag_characters:
                ;

                if (*f == L'*')
                {
                    ++f;
                    ++direc_length;
                    if (argc > 0)
                    {
                        intmax_t width = string_to_scalar_type<intmax_t>(*argv, this);
                        if (INT_MIN <= width && width <= INT_MAX)
                            field_width = static_cast<int>(width);
                        else
                            this->fatal_error(_(L"invalid field width: %ls"), *argv);
                        ++argv;
                        --argc;
                    }
                    else
                    {
                        field_width = 0;
                    }
                    have_field_width = true;
                }
                else
                {
                    while (iswdigit(*f))
                    {
                        ++f;
                        ++direc_length;
                    }
                }
                if (*f == L'.')
                {
                    ++f;
                    ++direc_length;
                    ok['c'] = false;
                    if (*f == L'*')
                    {
                        ++f;
                        ++direc_length;
                        if (argc > 0)
                        {
                            intmax_t prec = string_to_scalar_type<intmax_t>(*argv, this);
                            if (prec < 0)
                            {
                                /* A negative precision is taken as if the
                                precision were omitted, so -1 is safe
                                here even if prec < INT_MIN.  */
                                precision = -1;
                            }
                            else if (INT_MAX < prec)
                                this->fatal_error(_(L"invalid precision: %ls"), *argv);
                            else
                            {
                                precision = static_cast<int>(prec);
                            }
                            ++argv;
                            --argc;
                        }
                        else
                        {
                            precision = 0;
                        }
                        have_precision = true;
                    }
                    else
                    {
                        while (iswdigit(*f))
                        {
                            ++f;
                            ++direc_length;
                        }
                    }
                }

                while (*f == L'l' || *f == L'L' || *f == L'h' || *f == L'j' || *f == L't' || *f == L'z')
                    ++f;

                {
                    unsigned wchar_t conversion = *f;
                    if (! ok[conversion])
                    {
                        this->fatal_error(_(L"%.*ls: invalid conversion specification"), (int)(f + 1 - direc_start), direc_start);
                        return 0;
                    }
                }

                print_direc(direc_start, direc_length, *f,
                            have_field_width, field_width,
                            have_precision, precision,
                            (argc <= 0 ? L"" : (argc--, *argv++)));
                break;

            case L'\\':
                f += print_esc(f, false);
                break;

            default:
                this->append_output(*f);
        }
    }
    return save_argc - argc;
}
Example #28
0
void tex::conditional ()
	{
	bool	b=false;
	sym	s;
	int	m, n;
	ptr	p, q, r;
	int	this_if;
	ptr	save_cond_ptr;
	int	save_scanner_status;

	push_cond();
	save_cond_ptr = cond_ptr;
	this_if = cur_chr;
	switch (this_if) {
		case IF_CHAR_CODE:
		case IF_CAT_CODE:
			
#define get_x_token_or_active_char() {get_x_token(); \
	if (cur_cmd == RELAX && cur_chr == NO_EXPAND_FLAG) { \
		cur_cmd = ACTIVE_CHAR; \
		cur_chr = tok2sym(cur_tok) - active_base[0]; }}

		get_x_token_or_active_char();
		if (cur_cmd > ACTIVE_CHAR || cur_chr > 255) {
			m = RELAX;
			n = 256;
			} 
		else {
			m = cur_cmd;
			n = cur_chr;
			}
		get_x_token_or_active_char();
		if (cur_cmd > ACTIVE_CHAR || cur_chr > 255) {
			cur_cmd = RELAX;
			cur_chr = 256;
		}
		if (this_if == IF_CHAR_CODE) {
			b = n == cur_chr;
		} else {
			b = m == cur_cmd;
		}
		break;
	
	case IF_INT_CODE:
	case IF_DIM_CODE:
		if (this_if == IF_INT_CODE) {
			scan_int();
		} else {
			scan_normal_dimen();
		}
		n = cur_val;
		get_nbx_token(); 
		if (cur_tok >= OTHER_TOKEN + '<'
		&& cur_tok <= OTHER_TOKEN + '>') {
			r = cur_tok - OTHER_TOKEN;
		} else {
			print_err("Missing = inserted for ");
			print_cmd_chr(IF_TEST, this_if);
			help_relation();
			back_error();
			r = '=';
		}
		if (this_if == IF_INT_CODE) {
			scan_int();
		} else {
			scan_normal_dimen();
		}
		switch (r) {
		case '<': b = n < cur_val; break;
		case '=': b = n == cur_val; break; 
		case '>': b = n > cur_val; break;
		}
		break;
	
	case IF_ODD_CODE:
		scan_int();
		b = odd(cur_val);
		break;
	
	case IF_VMODE_CODE:
		b = abs(mode) == VMODE;
		break;

	case IF_HMODE_CODE:
		b = abs(mode) == HMODE;
		break;

	case IF_MMODE_CODE:
		b = abs(mode) == MMODE;
		break;
	
	case IF_INNER_CODE:
		b = mode < 0;
		break;
	
	case IF_VOID_CODE:
	case IF_HBOX_CODE:
	case IF_VBOX_CODE:
		scan_eight_bit_int();
		p = box(cur_val);
		if (this_if == IF_VOID_CODE) {
			b = p == null;
		} else if (p == null) {
			b = FALSE;
		} else if (this_if == IF_HBOX_CODE) {
			b = type(p) == HLIST_NODE;
		} else {
			b = type(p) == VLIST_NODE;
		}
		break;

	case IFX_CODE:
		save_scanner_status = scanner_status;
		scanner_status = NORMAL;
		get_next();
		s = cur_cs;
		p = cur_cmd;
		q = cur_chr;
		get_next(); 
		if (cur_cmd != p) {
			b = FALSE;
		} else if (cur_cmd < CALL) {
			b = cur_chr == q;
		} else {
			p = token_link(cur_chr);
			q = token_link(equiv(s));
			if (p == q) {
				b = TRUE;
			} else {
				while (p != null && q != null) {
					if (token(p) != token(q)) {
						p = null;
					} else {
						p = token_link(p);
						q = token_link(q);
					}
				}
				b = p == null && q == null;
			}
		}
		scanner_status = save_scanner_status;
		break;

	case IF_EOF_CODE:
		scan_four_bit_int();
		b = read_open[cur_val] == CLOSED;
		break;
	
	case IF_TRUE_CODE:
		b = TRUE;
		break;

	case IF_FALSE_CODE:
		b = FALSE;
		break;

	case IF_CASE_CODE: 
		scan_int();
		n = cur_val;
		if (tracing_commands > 1) {
			begin_diagnostic();
			print("{case ");
			print_int(n);
			print("}");
			end_diagnostic(FALSE);
		}
		while (n != 0) {
			pass_text();
			if (cond_ptr == save_cond_ptr) {
				if (cur_chr == OR_CODE) {
					decr(n);
				} else {
					goto common_end;
				}
			} else if (cur_chr == FI_CODE) {
				pop_cond();
			}
		}
		change_if_limit(OR_CODE, save_cond_ptr);
		return;
	
	default:
		break;
	}

	if (tracing_commands > 1) {
		begin_diagnostic();
		print(b ? "{true}" : "{false}");
		end_diagnostic(FALSE);
	}

	if (b) {
		change_if_limit(ELSE_CODE, save_cond_ptr);
		return;
	}

	loop {
		pass_text(); 
		if (cond_ptr == save_cond_ptr) {
			if (cur_chr != OR_CODE)
				goto common_end;
			print_err("Extra ");
			print_esc("or");
			help_or();
			error();
		} else if (cur_chr == FI_CODE) {
			pop_cond();
		}
	}

common_end:
	if (cur_chr == FI_CODE) {
		pop_cond();
	} else {
		if_limit = FI_CODE;
	}
}
Example #29
0
/// Print the text in FORMAT, using ARGV (with ARGC elements) for arguments to any `%' directives.
/// Return the number of elements of ARGV used.
int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wchar_t **argv) {
    int save_argc = argc;        /* Preserve original value.  */
    const wchar_t *f;            /* Pointer into `format'.  */
    const wchar_t *direc_start;  /* Start of % directive.  */
    size_t direc_length;         /* Length of % directive.  */
    bool have_field_width;       /* True if FIELD_WIDTH is valid.  */
    int field_width = 0;         /* Arg to first '*'.  */
    bool have_precision;         /* True if PRECISION is valid.  */
    int precision = 0;           /* Arg to second '*'.  */
    bool ok[UCHAR_MAX + 1] = {}; /* ok['x'] is true if %x is allowed.  */

    for (f = format; *f != L'\0'; ++f) {
        switch (*f) {
            case L'%': {
                direc_start = f++;
                direc_length = 1;
                have_field_width = have_precision = false;
                if (*f == L'%') {
                    this->append_output(L'%');
                    break;
                }
                if (*f == L'b') {
                    // FIXME: Field width and precision are not supported for %b, even though POSIX
                    // requires it.
                    if (argc > 0) {
                        print_esc_string(*argv);
                        ++argv;
                        --argc;
                    }
                    break;
                }

                modify_allowed_format_specifiers(ok, "aAcdeEfFgGiosuxX", true);
                for (bool continue_looking_for_flags = true; continue_looking_for_flags;) {
                    switch (*f) {
                        case L'I':
                        case L'\'': {
                            modify_allowed_format_specifiers(ok, "aAceEosxX", false);
                            break;
                        }
                        case '-':
                        case '+':
                        case ' ': {
                            break;
                        }
                        case L'#': {
                            modify_allowed_format_specifiers(ok, "cdisu", false);
                            break;
                        }
                        case '0': {
                            modify_allowed_format_specifiers(ok, "cs", false);
                            break;
                        }
                        default: {
                            continue_looking_for_flags = false;
                            break;
                        }
                    }
                    if (continue_looking_for_flags) {
                        f++;
                        direc_length++;
                    }
                }

                if (*f == L'*') {
                    ++f;
                    ++direc_length;
                    if (argc > 0) {
                        intmax_t width = string_to_scalar_type<intmax_t>(*argv, this);
                        if (INT_MIN <= width && width <= INT_MAX)
                            field_width = static_cast<int>(width);
                        else
                            this->fatal_error(_(L"invalid field width: %ls"), *argv);
                        ++argv;
                        --argc;
                    } else {
                        field_width = 0;
                    }
                    have_field_width = true;
                } else {
                    while (iswdigit(*f)) {
                        ++f;
                        ++direc_length;
                    }
                }
                if (*f == L'.') {
                    ++f;
                    ++direc_length;
                    modify_allowed_format_specifiers(ok, "c", false);
                    if (*f == L'*') {
                        ++f;
                        ++direc_length;
                        if (argc > 0) {
                            intmax_t prec = string_to_scalar_type<intmax_t>(*argv, this);
                            if (prec < 0) {
                                // A negative precision is taken as if the precision were omitted,
                                // so -1 is safe here even if prec < INT_MIN.
                                precision = -1;
                            } else if (INT_MAX < prec)
                                this->fatal_error(_(L"invalid precision: %ls"), *argv);
                            else {
                                precision = static_cast<int>(prec);
                            }
                            ++argv;
                            --argc;
                        } else {
                            precision = 0;
                        }
                        have_precision = true;
                    } else {
                        while (iswdigit(*f)) {
                            ++f;
                            ++direc_length;
                        }
                    }
                }

                while (*f == L'l' || *f == L'L' || *f == L'h' || *f == L'j' || *f == L't' ||
                       *f == L'z') {
                    ++f;
                }

                wchar_t conversion = *f;
                if (conversion > 0xFF || !ok[conversion]) {
                    this->fatal_error(_(L"%.*ls: invalid conversion specification"),
                                      (int)(f + 1 - direc_start), direc_start);
                    return 0;
                }

                print_direc(direc_start, direc_length, *f, have_field_width, field_width,
                            have_precision, precision, (argc <= 0 ? L"" : (argc--, *argv++)));
                break;
            }
            case L'\\': {
                f += print_esc(f, false);
                break;
            }
            default: {
                this->append_output(*f);
                break;
            }
        }
    }
    return save_argc - argc;
}
Example #30
0
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;
}