refactor, bring back basic.h and Slice<T>
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
#define panicf(...) (fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"), exit(1))
|
||||
#define lengthof(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
||||
#define panicf(...) (fprintf(stderr, "%s:%d: ", __FILE__, __LINE__), fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"), exit(1))
|
||||
#define debugf(...) (printf("%s:%d: ", __FILE__, __LINE__), printf(__VA_ARGS__), printf("\n"))
|
||||
#define assert(x) ((!(x)) && (panicf("%s:%d: assertion failed " #x, __FILE__, __LINE__), 0))
|
||||
|
||||
template <typename T>
|
||||
struct DEFER_ExitScope {
|
||||
@@ -20,3 +24,48 @@ class DEFER_ExitScopeHelp {
|
||||
#define DEFER_CONCAT_INTERNAL(x, y) x##y
|
||||
#define DEFER_CONCAT(x, y) DEFER_CONCAT_INTERNAL(x, y)
|
||||
#define defer const auto DEFER_CONCAT(defer__, __LINE__) = DEFER_ExitScopeHelp() + [&]()
|
||||
|
||||
char* strf(const char* format, ...) { // @leak
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int size = vsnprintf(NULL, 0, format, args_copy) + 1;
|
||||
va_end(args_copy);
|
||||
char* buffer = (char *)malloc(size);
|
||||
assert(buffer);
|
||||
vsnprintf(buffer, size, format, args);
|
||||
va_end(args);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct Slice {
|
||||
T *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
#define PLEN(x) {(x), lengthof(x)}
|
||||
|
||||
struct EnumValue {
|
||||
int value;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#define ENUM_VALUE(x) {x, #x}
|
||||
const char *serialize(Slice<EnumValue> table, int value) {
|
||||
for (int i = 0; i < table.len; i += 1) {
|
||||
EnumValue *it = table.data + i;
|
||||
if (it->value == value) return it->name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
char *serialize_flags(Slice<EnumValue> table, int n) { // @leak
|
||||
char *result = strf("%d", n);
|
||||
for (int i = 0; i < table.len; i += 1) {
|
||||
auto *it = table.data + i;
|
||||
if (n & it->value) result = strf("%s %s", result, it->name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
113
src/main.cpp
113
src/main.cpp
@@ -12,31 +12,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#pragma comment(lib, "ws2_32")
|
||||
|
||||
#define panicf(...) (fprintf(stderr, "%s:%d: ", __FILE__, __LINE__), fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"), exit(1))
|
||||
#define debugf(...) (printf("%s:%d: ", __FILE__, __LINE__), printf(__VA_ARGS__), printf("\n"))
|
||||
#define assert(x) ((!(x)) && (panicf("%s:%d: assertion failed " #x, __FILE__, __LINE__), 0))
|
||||
|
||||
template <typename T>
|
||||
struct DEFER_ExitScope {
|
||||
T lambda;
|
||||
DEFER_ExitScope(T lambda) : lambda(lambda) {}
|
||||
~DEFER_ExitScope() { lambda(); }
|
||||
DEFER_ExitScope(const DEFER_ExitScope &i) : lambda(i.lambda){};
|
||||
|
||||
private:
|
||||
DEFER_ExitScope &operator=(const DEFER_ExitScope &);
|
||||
};
|
||||
|
||||
class DEFER_ExitScopeHelp {
|
||||
public:
|
||||
template <typename T>
|
||||
DEFER_ExitScope<T> operator+(T t) { return t; }
|
||||
};
|
||||
|
||||
#define DEFER_CONCAT_INTERNAL(x, y) x##y
|
||||
#define DEFER_CONCAT(x, y) DEFER_CONCAT_INTERNAL(x, y)
|
||||
#define defer const auto DEFER_CONCAT(defer__, __LINE__) = DEFER_ExitScopeHelp() + [&]()
|
||||
#include "basic.cpp"
|
||||
|
||||
char *serialize_error_code(DWORD errorCode) {
|
||||
char* message = NULL;
|
||||
@@ -58,98 +34,49 @@ char *serialize_error_code(DWORD errorCode) {
|
||||
if (newline) *newline = '\0';
|
||||
}
|
||||
|
||||
return message; // Remember to LocalFree() this later!
|
||||
return message; // @leak - LocalFree
|
||||
}
|
||||
|
||||
char* strf(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
int size = vsnprintf(NULL, 0, format, args_copy) + 1;
|
||||
va_end(args_copy);
|
||||
char* buffer = (char *)malloc(size);
|
||||
assert(buffer);
|
||||
vsnprintf(buffer, size, format, args);
|
||||
va_end(args);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#define lengthof(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
||||
struct EnumValue {
|
||||
int value;
|
||||
const char *name;
|
||||
};
|
||||
#define ENUM_VALUE(x) {x, #x}
|
||||
const char *serialize(EnumValue *table, int table_size, int value) {
|
||||
for (int i = 0; i < table_size; i += 1) {
|
||||
EnumValue *it = table + i;
|
||||
if (it->value == value) return it->name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
EnumValue ai_flag_table[] = {
|
||||
EnumValue _ai_flags_table[] = {
|
||||
ENUM_VALUE(AI_PASSIVE),
|
||||
ENUM_VALUE(AI_CANONNAME),
|
||||
ENUM_VALUE(AI_NUMERICHOST),
|
||||
};
|
||||
Slice<EnumValue> ai_flags_table = PLEN(_ai_flags_table);
|
||||
|
||||
char *serialize_ai_flags(int n) {
|
||||
char *result = strf("%d", n);
|
||||
for (int i = 0; i < lengthof(ai_flag_table); i += 1) {
|
||||
auto *it = ai_flag_table + i;
|
||||
if (n & it->value) result = strf("%s %s", result, it->name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct {
|
||||
const char *name;
|
||||
int value;
|
||||
const char *desc;
|
||||
} ai_family_table[] = {
|
||||
{"AF_UNSPEC", 0, "The address family is unspecified"},
|
||||
{"AF_INET", 2, "The Internet Protocol version 4 (IPv4) address family."},
|
||||
{"AF_NETBIOS", 17, "The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed."},
|
||||
{"AF_INET6", 23, "The Internet Protocol version 6 (IPv6) address family."},
|
||||
{"AF_IRDA", 26, "The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared port and driver installed."},
|
||||
{"AF_BTH", 32, "The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server 2003 or later."},
|
||||
EnumValue _ai_family_table[] = {
|
||||
{0, "AF_UNSPEC"},
|
||||
{2, "AF_INET"},
|
||||
{17, "AF_NETBIOS"},
|
||||
{23, "AF_INET6"},
|
||||
{26, "AF_IRDA"},
|
||||
{32, "AF_BTH"},
|
||||
};
|
||||
Slice<EnumValue> ai_family_table = PLEN(_ai_family_table);
|
||||
|
||||
const char *serialize_ai_family(int n) {
|
||||
for (int i = 0; i < lengthof(ai_family_table); i += 1) {
|
||||
auto *it = ai_family_table + i;
|
||||
if (it->value == n) {
|
||||
return it->name;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
EnumValue ai_socktype_table[] = {
|
||||
EnumValue _ai_socktype_table[] = {
|
||||
ENUM_VALUE(SOCK_STREAM),
|
||||
ENUM_VALUE(SOCK_DGRAM),
|
||||
ENUM_VALUE(SOCK_RAW),
|
||||
ENUM_VALUE(SOCK_RDM),
|
||||
ENUM_VALUE(SOCK_SEQPACKET),
|
||||
};
|
||||
Slice<EnumValue> ai_socktype_table = PLEN(_ai_socktype_table);
|
||||
|
||||
EnumValue ai_protocol_table[] = {
|
||||
EnumValue _ai_protocol_table[] = {
|
||||
ENUM_VALUE(IPPROTO_TCP),
|
||||
ENUM_VALUE(IPPROTO_UDP),
|
||||
ENUM_VALUE(IPPROTO_PGM),
|
||||
};
|
||||
Slice<EnumValue> ai_protocol_table = PLEN(_ai_protocol_table);
|
||||
|
||||
void serialize_addrinfo(struct addrinfo* in) {
|
||||
for (struct addrinfo* p = in; p != NULL; p = p->ai_next) {
|
||||
printf("addrinfo %p {\n", p);
|
||||
printf(" ai_flags = %s(%d)\n", serialize_ai_flags(p->ai_flags), p->ai_flags);
|
||||
printf(" ai_family = %s(%d)\n", serialize_ai_family(p->ai_family), p->ai_family);
|
||||
printf(" ai_socktype = %s(%d)\n", serialize(ai_socktype_table, lengthof(ai_socktype_table), p->ai_socktype), p->ai_socktype);
|
||||
printf(" ai_protocol = %s(%d)\n", serialize(ai_protocol_table, lengthof(ai_protocol_table), p->ai_protocol), p->ai_protocol);
|
||||
printf(" ai_flags = %s(%d)\n", serialize_flags(ai_flags_table, p->ai_flags), p->ai_flags);
|
||||
printf(" ai_family = %s(%d)\n", serialize(ai_family_table, p->ai_family), p->ai_family);
|
||||
printf(" ai_socktype = %s(%d)\n", serialize(ai_socktype_table, p->ai_socktype), p->ai_socktype);
|
||||
printf(" ai_protocol = %s(%d)\n", serialize(ai_protocol_table, p->ai_protocol), p->ai_protocol);
|
||||
printf(" ai_addrlen = %zu\n", p->ai_addrlen);
|
||||
printf(" ai_canonname = \"%s\"\n", p->ai_canonname ? p->ai_canonname : "");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user