main_with_catch.h

#ifndef MAINCATCH_H__
#define MAINCATCH_H__

#include <vector>
#include <cstdio>
#include <ctime>
#include <sstream>
#include <stdexcept>
#include <string>
#include <iostream>

#if defined(_MSC_VER)
# include <fcntl.h>
# include <io.h>
#endif

namespace MainCatch
{
	/*int_types*/
	typedef signed char      int8_t;
	typedef signed short     int16_t;
	typedef signed int       int32_t;
#if defined(__i386__) || defined(__ppc__) || defined(_MSC_VER)
	typedef signed long long int64_t;
#else
	typedef signed long      int64_t;
#endif

	/*stop_info*/
	typedef std::ptrdiff_t ssize_t;
	struct stop_info : public std::exception
	{
		std::string source_file;
		size_t source_line;
		ssize_t digits;
		std::string message;

	protected:
		mutable std::string what_buffer;

	public:

		stop_info(
			const char* source_file_,
			size_t source_line_,
			ssize_t digits_) throw()
			:
			source_file(source_file_),
			source_line(source_line_),
			digits(digits_)
		{}

		stop_info(
			const char* source_file_,
			size_t source_line_,
			std::string const& message_) throw()
			:
			source_file(source_file_),
			source_line(source_line_),
			digits(-1),
			message(message_)
		{}

		~stop_info() throw() {}

		const char*
			what() const throw()
		{
				if (what_buffer.size() == 0) {
					std::ostringstream o;
					o << "STOP at " << source_file << "(" << source_line << ")";
					if (message.size() != 0) {
						o << ": " << message;
					}
					else if (digits > 0) {
						o << ": code=" << digits;
					}
					what_buffer = o.str();
					what_buffer.push_back('\0');
				}
				return what_buffer.data();
			}
	};

	/**/
	inline	double	user_plus_system_time()
	{
		static std::clock_t t_start = std::clock();
		return static_cast<double>(std::clock() - t_start)
			/ static_cast<double>(CLOCKS_PER_SEC);
	}

	/**/
	inline	bool check_int_types()
	{
		bool result = true;
#define FABLE_LOC(bits, expected_sz) \
		{ \
		int sz = static_cast<int>(sizeof(int##bits##_t)); \
		if (sz != expected_sz) {\
			std::fprintf(stderr, \
			"FATAL: sizeof(int%d_t) is %d but should be %d.\n", \
			bits, sz, expected_sz); \
			result = false; \
		} \
		}
		FABLE_LOC(8, 1)
		FABLE_LOC(16, 2)
		FABLE_LOC(32, 4)
		FABLE_LOC(64, 8)
#undef FABLE_LOC
		if (!result) {
			std::fprintf(stderr,
				"NOTE: int_types"
				" needs to be adjusted for this platform.\n");
		}
		return result;
	}

	inline
		int
		main_with_catch(
		int argc,
		char const* argv[],
		void(*callable)(int argc, char const* argv[]))
	{
			user_plus_system_time();
			if (!check_int_types()) {
				return 255;
			}
#if defined(_MSC_VER)
			if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
				std::cerr
					<< "FATAL: error switching stdin to binary mode ("
					<< __FILE__ << ", line " << __LINE__ << ")" << std::endl;
				return 255;
			}
#endif
			try {
				callable(argc, argv);
			}
			catch (stop_info const& info) {
				std::fflush(stdout);
				std::fprintf(stderr, "%s\n", info.what());
				std::fflush(stderr);
			}
			catch (std::exception const& e) {
				std::fflush(stdout);
				char const* what = e.what();
				if (what == 0) what = "null";
				std::fprintf(stderr, "std::exception what(): %s\n", what);
				std::fflush(stderr);
				return 1;
			}
			catch (...) {
				std::fflush(stdout);
				std::fprintf(stderr, "Terminated by unknown C++ exception.\n");
				std::fflush(stderr);
				return 2;
			}
			return 0;
		}	
}// namespace MainCatch

#define MAINCATCH_STOP(arg) \
	throw MainCatch::stop_info(__FILE__, __LINE__, arg)

/*//how to use
void
program_test(
int argc,
char const* argv[])
{

}

int
main(
int argc,
char const* argv[])
{
	return MainCatch::main_with_catch(
		argc, argv,
		program_test);
}
*/
#endif // MAINCATCH_H__
发布了38 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/sinat_31964903/article/details/87799907