A collection of basic/generally desirable code I use across multiple C++ projects.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

185 lines
6.0 KiB

#pragma once
#ifndef ULE_PRINT_H
#define ULE_PRINT_H
#include <stdarg.h> // va_list
#include "config.h"
#include "string.h"
#include "types.h"
#ifndef _WIN32
// comment this line out if you don't want terminal output to contain ANSI escape codes
// by default on windows executables it's disabled, since things like the command prompt still doesn't support ANSI color codes
#define PRINT_H_USE_ANSI_COLOR_ESCAPE_CODES
#endif
#ifdef PRINT_H_USE_ANSI_COLOR_ESCAPE_CODES
#define ANSI_BLACK "\x001B[30m"
#define ANSI_RED "\x001B[31m"
#define ANSI_GREEN "\x001B[32m"
#define ANSI_YELLOW "\x001B[33m"
#define ANSI_BLUE "\x001B[34m"
#define ANSI_PURPLE "\x001B[35m"
#define ANSI_CYAN "\x001B[36m"
#define ANSI_WHITE "\x001B[37m"
#define ANSI_BRIGHT_BLACK "\x001B[90m"
#define ANSI_BRIGHT_RED "\x001B[91m"
#define ANSI_BRIGHT_GREEN "\x001B[92m"
#define ANSI_BRIGHT_YELLOW "\x001B[93m"
#define ANSI_BRIGHT_BLUE "\x001B[94m"
#define ANSI_BRIGHT_MAGENTA "\x001B[95m"
#define ANSI_BRIGHT_CYAN "\x001B[96m"
#define ANSI_BRIGHT_WHITE "\x001B[97m"
#define ANSI_BLACK_BACKGROUND "\x001B[40m"
#define ANSI_RED_BACKGROUND "\x001B[41m"
#define ANSI_GREEN_BACKGROUND "\x001B[42m"
#define ANSI_YELLOW_BACKGROUND "\x001B[43m"
#define ANSI_BLUE_BACKGROUND "\x001B[44m"
#define ANSI_PURPLE_BACKGROUND "\x001B[45m"
#define ANSI_CYAN_BACKGROUND "\x001B[46m"
#define ANSI_WHITE_BACKGROUND "\x001B[47m"
#define ANSI_WRAP "\x001B[7m"
#define ANSI_BLINK "\x001B[5m"
#define ANSI_CLEAR "\x001B[2J\x001B[;H"
#define ANSI_RESET "\x001B[0m"
#else
#define ANSI_BLACK ""
#define ANSI_RED ""
#define ANSI_GREEN ""
#define ANSI_YELLOW ""
#define ANSI_BLUE ""
#define ANSI_PURPLE ""
#define ANSI_CYAN ""
#define ANSI_WHITE ""
#define ANSI_BRIGHT_BLACK ""
#define ANSI_BRIGHT_RED ""
#define ANSI_BRIGHT_GREEN ""
#define ANSI_BRIGHT_YELLOW ""
#define ANSI_BRIGHT_BLUE ""
#define ANSI_BRIGHT_MAGENTA ""
#define ANSI_BRIGHT_CYAN ""
#define ANSI_BRIGHT_WHITE ""
#define ANSI_BLACK_BACKGROUND ""
#define ANSI_RED_BACKGROUND ""
#define ANSI_GREEN_BACKGROUND ""
#define ANSI_YELLOW_BACKGROUND ""
#define ANSI_BLUE_BACKGROUND ""
#define ANSI_PURPLE_BACKGROUND ""
#define ANSI_CYAN_BACKGROUND ""
#define ANSI_WHITE_BACKGROUND ""
#define ANSI_WRAP ""
#define ANSI_BLINK ""
#define ANSI_CLEAR ""
#define ANSI_RESET ""
#endif
extern void vprint(const char* format, va_list args);
extern void vprintln(const char* format, va_list args);
extern void print(const char* format, ...);
extern void println(const char* format, ...);
// prints the |count| * 8 little endian bits pointed to by |ptr|
extern void printBitsLE(const size_t count, void* ptr);
// Prints a stack trace, or concatenates the stack trace to |string| if it is not null.
extern void trace(String* string = null);
// on windows only
extern void writeMinidump(void* exceptionPointers);
// This ends the program and calls trace(). generally you should use 'massert' instead
void _die(
const char* date,
const char* time,
const char* filename,
const int line,
const char* format,
...
);
#define die(format, ...) _die(__DATE__, __TIME__, __FILE__, __LINE__, format, ##__VA_ARGS__)
// when calling 'die', instead of the default behavior,
// (print a stack trace and then call 'exit(1)')
// do something else.
//
// The function will get passed a string which is the formatted string you passed to 'die' + a stack trace.
extern void setCustomDieBehavior(void (*dieBehavior)(const char* string));
#ifdef PRINT_DEBUG
// simple wrapper to allow custom messages...
//#define massert(test, message) (((void)(message), test))
#define massert(test, message) if (!(test)) die("%s\n", message);
extern void _debug(
const char* date,
const char* time,
const char* filename,
const int line,
const char* format,
...
);
#define debug(format, ...) _debug(__DATE__, __TIME__, __FILE__, __LINE__, format, ##__VA_ARGS__)
// @NOTE there's a conflict on win32 with the name 'warning'...
extern void _warn(
const char* date,
const char* time,
const char* filename,
const int line,
const char* format,
...
);
#define warn(format, ...) _warn(__DATE__, __TIME__, __FILE__, __LINE__, format, ##__VA_ARGS__)
#else
// define some empty macros
#define massert(test, message) ((void) 0)
#define debug(format, ...)
#define warn(format, ...)
#endif
extern void print(bool b);
extern void print(char c);
extern void print(signed int i);
extern void print(unsigned int i);
extern void print(float f);
extern void print(double d);
extern void print(void* p);
extern void print(char* s);
#ifndef _WIN32
extern void print(size_t i);
extern void println(size_t i);
#endif
extern void println(bool b);
extern void println(char c);
extern void println(signed int i);
extern void println(unsigned int i);
extern void println(float f);
extern void println(double d);
extern void println(void* p);
extern void println(char* s);
extern void println();
#ifdef ULE_CONFIG_OPTION_USE_GLM
extern void print(glm::vec<2, float, (glm::qualifier) 3>);
extern void print(glm::vec<3, float, (glm::qualifier) 3>);
extern void print(glm::vec<4, float, (glm::qualifier) 3>);
extern void print(glm::mat<2, 2, float, (glm::qualifier) 3>);
extern void print(glm::mat<3, 3, float, (glm::qualifier) 3>);
extern void print(glm::mat<4, 4, float, (glm::qualifier) 3>);
extern void println(glm::vec<2, float, (glm::qualifier) 3> v);
extern void println(glm::vec<3, float, (glm::qualifier) 3> v);
extern void println(glm::vec<3, float, (glm::qualifier) 3> v);
extern void println(glm::mat<2, 2, float, (glm::qualifier) 3> m);
extern void println(glm::mat<3, 3, float, (glm::qualifier) 3> m);
extern void println(glm::mat<4, 4, float, (glm::qualifier) 3> m);
#endif
#endif