⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 echo.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include <ctype.h>#include <stdio.h>#include <string.h>#include "inttypes.hh"#include "sulima.hh"// echo() is a simplified printf-like function that writes up to (max - 1)// characters to the (buf) array, followed by a NUL.//// The following formatting fields are recognised and have the usual meaning:// %%, %c, %d, %i, %o, %s, %u, %x, and %X.  Further, the "l" option may be// inserted before the format characters "d", "i", "o", "u", "x" and "X" to// indicate that the corresponding argument is an Int64/UInt64. If "l" is// ommited, the argument is interpreted as an Int32/UInt32. Also, the "#" flag// may be inserted after "%" is the %c, %s, %o, %x and %X fields.  In the %o,// %x and %X field, it has the usual effect of printing the number as a C// constant. In a %c field, it indicates that non-printable characters should// be converted to the ^X (if possible) or \xxx escape sequence (this includes// \t and \v.)  In a %s field, it escapes all non-printable characters except// for spaces which are compressed to a single space. The '0', '+', '-' and '// ' flags and the field width specifier may also preceed the format// character.  Note that the %p format specifier, the precision field, the '*'// syntax and the XPG4 '`' flag and '$' syntax are not supported.//// All that said, echo() wouldn't be worth the bother if the code had to be// written from scratch ;)struct State {    char *p, *end;};// Write a single character.inline voidechoc(State &state, char c){    if (state.p < state.end) {	*(state.p)++ = c;    }}// Echo an octal, decimal or hexadecimal number.// (hex_case) is either 'a' or 'A'.// (nice) is true if the '#' flag is specified.// (padding) is the left-padding character.// (sign) is set to the prevailing '+' or ' ' flag, or is 0.// (signed) is true for signed conversions// (width) is the field width, negated for the '-' flag.static voidecho_oct(State &state, UInt64 x,	 char padding, int width, bool nice){    // Don't print the initial '0' in front of a 0.    if (!x)	nice = false;    // Align left if width is negative.    bool flush_left;    if (width >= 0)	flush_left = false;    else {	flush_left = true;	width = -width;    }    // Generate the digits (least-signficant one first.)    char buffer[(sizeof(x) * 8 + 2) / 3 + 2], *p = buffer;    do {	*p++ = (x & 7) + '0';    } while (x >>= 3);    // Print the 'nice' zero.    if (nice)	*p++ = '0';    // Adjust the width by the number of already-generated characters.    width -= (p - buffer);    // Print the left padding.    if (!flush_left)	for (; width > 0; --width)	    echoc(state, padding);    // Print the generated digits in a reversed order.    do {	echoc(state, *--p);    } while (p > buffer);    // Print the right padding.    for (; width > 0; --width)	echoc(state, ' ');}static voidecho_dec(State &state, UInt64 x,	 char padding, int width, bool is_signed, char sign){    // For signed conversions, grab the absolute value of the number.    if (!is_signed)	sign = 0;    else {	// Process the sign and distard it from x.	if ((Int64)x < 0) {	    sign = '-';	    x = -x;	}    }    // Align left if width is negative.    bool flush_left;    if (width >= 0)	flush_left = false;    else {	flush_left = true;	width = -width;    }    // Generate the digits (least-signficant one first.)    // The buffer size uses log10(2) == 0.30103.    char buffer[sizeof(x) * 8 * 30103L / 100000L + 2], *p = buffer;    do {	*p++ = (x % 10) + '0';    } while (x /= 10);    // Print the sign character.    if (sign)	*p++ = sign;    // Adjust the width by the number of already-generated characters.    width -= (p - buffer);    // Print the left padding.    if (!flush_left)	for (; width > 0; --width)	    echoc(state, padding);    // Print the generated digits in a reversed order.    do {	echoc(state, *--p);    } while (p > buffer);    // Print the right padding.    for (; width > 0; --width)	echoc(state, ' ');}static voidecho_hex(State &state, UInt64 x,	 char padding, int width, bool nice, char hex_case){    // Align left if width is negative.    bool flush_left;    if (width >= 0)	flush_left = false;    else {	flush_left = true;	width = -width;    }    // Generate the digits (least-signficant one first.)    char buffer[sizeof(x) * 8 / 4 + 2], *p = buffer;    do {	int digit = x & 15;	*p++ = digit + (digit < 10 ? '0' : hex_case - 10);    } while (x >>= 4);    // Print the 'nice' 0x.    if (nice) {	*p++ = 'x' - 'a' + hex_case;	*p++ = '0';    }    // Adjust the width by the number of already-generated characters.    width -= (p - buffer);    // Print the left padding.    if (!flush_left) {	for (; width > 0; --width)	    echoc(state, padding);    }    // Print the generated digits in a reversed order.    do {	echoc(state, *--p);    } while (p > buffer);    // Print the right padding.    for (; width > 0; --width)	echoc(state, ' ');}// Echo a character or a string.static voidecho_chr(State &state, char c, int width, bool nice){    unsigned char x = c;    if (!nice || (x >= ' ' && x < '\177')) {	while (width > 1) {	    // Pad on the left.	    echoc(state, ' ');	    --width;	}	echoc(state, x);	while (width < -1) {	    // Pad on the right.	    echoc(state, ' ');	    ++width;	}    }    else if (x > '\177') {	while (width > 4) {	    // Pad on the left.	    echoc(state, ' ');	    --width;	}	echoc(state, '\\');	echoc(state, (x >> 6) & 7);	echoc(state, (x >> 3) & 7);	echoc(state, (x >> 0) & 7);	while (width < -4) {	    // Pad on the right.	    echoc(state, ' ');	    ++width;	}    }    else {	while (width > 2) {	    // Pad on the left.	    echoc(state, ' ');	    --width;	}	echoc(state, '^');	echoc(state, (x + '@') & 127);	width -= 2;	while (width < -2) {	    // Pad on the right.	    echoc(state, ' ');	    ++width;	}    }}static voidecho_str(State &state, const char *str, int width, bool nice){    int length = 0;    if (width) {	if (!nice)	    length = strlen(str);	else {	    for (const char *p = str; *p; ++p) {		unsigned char x = *p;		if ((x >= ' ' && x < '\177') || isspace(x))		    ++length;		else if (x > '\177')		    length += 4;		else		    length += 2;	    }	}    }    while (width > length) {	// Pad on the left.	echoc(state, ' ');	--width;    }    if (!nice) {	while (*str)	    echoc(state, *str++);    }    else {	while (*str) {	    unsigned char x = *str++;	    if ((x >= ' ' && x < '\177') || isspace(x))		echoc(state, x);	    else if (x > '\177') {		echoc(state, '\\');		echoc(state, (x >> 6) & 7);		echoc(state, (x >> 3) & 7);		echoc(state, (x >> 0) & 7);	    }	    else {		echoc(state, '^');		echoc(state, (x + '@') & 127);	    }	}    }    while (width < -length) {	// Pad on the right.	echoc(state, ' ');	++width;    }}// The actual global interfaces.size_techo(char *buffer, size_t size, const char *templ, ...){    va_list ap;    va_start(ap, templ);    size = vecho(buffer, size, templ, ap);    va_end(ap);    return size;}size_tvecho(char *buffer, size_t size, const char *templ, va_list ap){    State state;    const char *p;    UInt64 x;    /* Initialize the state. */    state.p   = buffer;    state.end = buffer + size - 1;        /* Process the template. */    for (p = templ; *p; ++p) {	if (*p != '%' || *++p == '%')	    echoc(state, *p);	else {	    bool left = false;	// - flag	    bool nice = false;	// # flag	    char padding = ' ';	// 0 flag	    char sign = 0;	// + and ' ' flags	    int  width = 0;	// - flag and the field width	    bool lflag;		// l modifier	    // Process a format specifier flags.	    for (;;) {		char flag = *p++;		if (flag == '-')		    left = true;		else if (flag == '+')		    sign = '+';		else if (flag == ' ')		    sign = (sign ? sign : ' ');		else if (flag == '#')		    nice = true;		else if (flag == '0')		    padding = '0';		else {		    --p;		    break;		}	    }	    // Process the field width.	    char digit = *p++;	    while (digit >= '0' && digit <= '9') {		width = width * 10 + digit - '0';		digit = *p++;	    }	    --p;	    if (left)		width = -width;	    // Process the "l" format modifier.	    if (*p != 'l')		lflag = false;	    else {		lflag = true;		++p;	    }	    // Process the format specifier.	    switch (*p) {	    case 'c':		echo_chr(state, va_arg(ap, int), width, nice);		break;	    case 'd':	    case 'i':		x = (lflag ? va_arg(ap, Int64) : (Int64)va_arg(ap, Int32));		echo_dec(state, x, padding, width, true, sign);		break;	    case 'o':		x = (lflag ? va_arg(ap, UInt64) : (Int64)va_arg(ap, UInt32));		echo_oct(state, x, padding, width, nice);		break;	    case 's':		echo_str(state, va_arg(ap, const char *), width, nice);		break;	    case 'u':		x = (lflag ? va_arg(ap, UInt64) : (Int64)va_arg(ap, UInt32));		echo_dec(state, x, padding, width, false, sign);		break;	    case 'x':		x = (lflag ? va_arg(ap, UInt64) : (Int64)va_arg(ap, UInt32));		echo_hex(state, x, padding, width, nice, 'a');		break;	    case 'X':		x = (lflag ? va_arg(ap, UInt64) : (Int64)va_arg(ap, UInt32));		echo_hex(state, x, padding, width, nice, 'A');		break;	    }	}    }    // NUL-terminate the string and return the number of characters generated.    *(state.p) = '\0';    return (state.p - buffer);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -