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

📄 log.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include <assert.h>#include <ctype.h>#include <errno.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "module.hh"#include "serial.hh"#include "sulima.hh"// Log-related variables.//// log_enabled, if non-zero, enables logging facilities//// rotate_log_files specifies the maximum number of old log files to retain.// Setting this to 0 will disable backing up of old log files.//// log_file_name specifies the name of the log file.//// log_created and log_fp are internal variables. log_created is set by the// first call to open_log(). log_fp is valid if log_created is non-zero and// open_log() succeeded.//// log_bol and print_bol, when true, indicate that the last character written// to the log file or the standard output was a newline.//// log_console points to the last module to write to the log file.static int   log_enabled = true;	// logging to file enabled/disabled static int   rotate_log_files = 9;	// maximum number of log files to keep static char *log_file_name = 0;		// log file name static bool  log_created = false;	// set after log is created static FILE *log_fp = 0;		// log stream static bool  log_bol = true;static bool  print_bol = true;static const BasicModule *log_console = 0;// Return a log name with a numeric suffix attached.static char *generate_log_name(int s){    // Don't do anything fancy if s is 0.    if (!s)	return copy(log_file_name);    // The buffer size uses log10(2) == 0.30103.    char buffer[sizeof(int) * 8 * 30103L / 100000L + 2];    size_t n;    int prec = 0;    // Grab the precision of the suffix.     int i = rotate_log_files;    do {	++prec;	i /= 10;    } while (i);    n += prec + 1;    // Generate the string.    sprintf(buffer, ".%0*d", prec, s);    return copy(log_file_name, buffer, 0);}// Create the log file. The log rotation code isn't particularly efficient if// the rotation period is large (it's fine if the actual number of existing// logs aproaches the rotation period.)  This should probably be fixed; for// now, I set the default period to a somewhat unsatisfactory 9 logs.static intopen_log(void){    log_created = true;    if (log_enabled) {	if (rotate_log_files) {	    // Rotate the log files, ignoring any errors. 	    char *name1 = 0, *name2 = 0;	    int i = rotate_log_files;	    if ((name1 = generate_log_name(i)) == 0)		return -1;	    remove(name1);	    while (i) {		if ((name2 = generate_log_name(--i)) == 0) {		    delete name1;		    delete name2;		    return -1;		}		rename(name2, name1);		delete name1;		name1 = name2;	    }	    delete name1;	}	// This cannot be called from the Sulima constructor.	assert(sulima);	// Create the new log file. 	if ((log_fp = fopen(log_file_name, "w")) == 0) {	    sulima->msg("Cannot open log file \"%#s\" (%s)",			log_file_name, strerror(errno));	    return -1;	}	// Write the banner and the time stamp. 	time_t t; time(&t);	fprintf(log_fp,		"%s\n"		"%s\n"		"Log file created on %s\n",		sulima->banner, sulima->copyright, ctime(&t));	if (ferror(log_fp)) {	    sulima->msg("Cannot write to the log file \"%#s\" (%s)",			log_file_name, strerror(errno));	    return -1;	}	setbuf(log_fp, NULL);    }    return 0;}// Write a character to the log file. If we've just switched consoles, start a// new line in the log file.voidBasicModule::log(char c) const{    if (!log_created)	open_log();    if (log_fp && !ferror(log_fp)) {	if (this != log_console && log_console) {	    putc('\n', log_fp);	    log_bol = true;	    log_console = this;	}	if (log_bol) {	    fputs(name(), log_fp);	    putc(':', log_fp);	    putc(' ', log_fp);	}	if (c == '\n') {	    putc(c, log_fp);	    log_bol = true;	}	else {	    if (c == '\\') {		putc('\\', log_fp);		putc(c, log_fp);	    }	    else if (isprint(c) || c == '\t') {		putc(c, log_fp);	    }	    else {		putc('\\', log_fp);		putc(((c >> 6) & 7) + '0', log_fp);		putc(((c >> 3) & 7) + '0', log_fp);		putc(((c)      & 7) + '0', log_fp);	    }	    log_bol = false;	}	if (ferror(log_fp)) {	    msg("Cannot write to log file \"%#s\" (%s)", 		log_file_name, strerror(errno));	}    }}// Write a character to the log file, maintaining the print_bol variable.voidBasicModule::msg(char c) const{    log(c);    putchar(c);    print_bol = (c == '\n');}// Print and log the module name, followed by : ", followed by a printf-like// one-line message. The message is always started on a new line and followed// by a '\n'. There's an upper limit on the total length of the message, but// what do we care?static voidprint_message(FILE *fp, const BasicModule *mod, const char *templ, va_list ap){    char buf[4096];    fputs(mod->name(), fp);    putc(':', fp);    putc(' ', fp);    size_t i = vecho(buf, sizeof(buf), templ, ap);    fputs(buf, fp);    if (i >= sizeof(buf))	fputs("...", fp);    putc('\n', fp);}// Log a message.voidBasicModule::log(const char *templ, ...) const{    va_list ap;    if (!log_created)	open_log();    if (log_fp && !ferror(log_fp)) {	va_start(ap, templ);	if (!log_bol)	    putc('\n', log_fp);	print_message(log_fp, this, templ, ap);	va_end(ap);	if (ferror(log_fp)) {	    msg("Cannot write to log file \"%#s\" (%s)",		log_file_name, strerror(errno));	}    }    log_bol = true;}// Print a message to the standard output.voidBasicModule::msg(const char *templ, ...) const{    va_list ap;    va_start(ap, templ);    if (!print_bol)	putc('\n', log_fp);    print_message(stdout, this, templ, ap);    va_end(ap);    print_bol = true;    if (!log_created)	open_log();    if (log_fp && !ferror(log_fp)) {	va_start(ap, templ);	if (!log_bol)	    putc('\n', log_fp);	print_message(log_fp, this, templ, ap);	va_end(ap);	if (ferror(log_fp)) {	    msg("Cannot write to log file \"%#s\" (%s)",		log_file_name, strerror(errno));	}    }    log_bol = true;}// The "sim::log" and "sim::msg" commands.static SimArglog_func(const SimArgs &args){    for (int i = 0; i < args.length(); ++i) {	for (const char *p = args[i]; *p; ++p)	    sulima->log(*p);	if (i < args.length())	    sulima->log(' ');    }    sulima->log('\n');    return "";}static SimArgmsg_func(const SimArgs &args){    for (int i = 0; i < args.length(); ++i) {	for (const char *p = args[i]; *p; ++p) {	    sulima->msg(*p);	}	if (i < args.length()) {	    sulima->msg(' ');	}    }    sulima->msg('\n');    return "";}// Initialize the logging subsystem.voidSulima::create_logging_subsystem(){    // Link related variables.     define("log_enabled", log_enabled, true);    define("rotate_log_files", rotate_log_files, 9);    define("log_file_name", log_file_name, "sulima.log");    define("log", log_func);    define("msg", msg_func);}// Destroy the logging subsystem.voidSulima::destroy_logging_subsystem(){    if (!log_file_name)	log_file_name = "?";    if (log_created && log_fp) {	if (fclose(log_fp)) {	    msg("Cannot write to log file \"%#s\" (%s)",		log_file_name, strerror(errno));	}	log_fp = 0;    }}

⌨️ 快捷键说明

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