#ifndef _COMMON_H #define _COMMON_H #include #include #include #include #include /* enums */ enum configurations_bitshift { C_BITSHIFT_CONFIRM = 0, C_BITSHIFT_CONTENTS, C_BITSHIFT_LINE_ENDINGS, C_BITSHIFT_PRINTABLE, C_BITSHIFT_CUSTOM_SEED }; enum configurations { C_CONFIRM = 1 << C_BITSHIFT_CONFIRM, C_CONTENTS = 1 << C_BITSHIFT_CONTENTS, C_LINE_ENDINGS = 1 << C_BITSHIFT_LINE_ENDINGS, C_PRINTABLE = 1 << C_BITSHIFT_PRINTABLE, C_CUSTOM_SEED = 1 << C_BITSHIFT_CUSTOM_SEED }; /* macros: procedures */ #define FPRINTF_MACRO(stream, ...) do { \ fflush(stdout); \ fprintf(stream, __VA_ARGS__); \ } while (0) /* // Intel A80486DX2-66: doesn't compile on my system // TODO: remove this multi-line comment before merging into main branch #define PERROR_MACRO(s) do { \ fflush(stdout); \ int errnum = errno; \ size_t err_msg_size = 256; \ char *err_msg = NULL; \ int ret = -1; \ do { \ err_msg_size *= 2; \ char* new_err_msg = realloc(err_msg, err_msg_size); \ if (new_err_msg == NULL) { \ free(err_msg); \ break; \ } \ err_msg = new_err_msg; \ ret = strerror_r(errnum, err_msg, err_msg_size); \ } while (ret == -1 && errno == ERANGE); \ if (ret == 0) { \ fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, (s), err_msg); \ } \ free(err_msg); \ } while (0) */ #define PERROR_MACRO(s) do { \ int errnum = errno; \ char* err_msg = strerror(errnum); \ fflush(stdout); \ fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, (s), err_msg); \ } while (0) #define FATAL_ERROR_PRINT(...) \ FPRINTF_MACRO(stderr, __VA_ARGS__); \ putc('\n', stderr) #define FATAL_ERROR(...) do { \ FATAL_ERROR_PRINT(__VA_ARGS__); \ exit(EXIT_FAILURE); \ } while (0) #define FATAL_ERROR_RET(...) do { \ FATAL_ERROR_PRINT(__VA_ARGS__); \ return EXIT_FAILURE; \ } while (0) /* macros: lambdas */ #define STRINGIZE(x) #x #define INT2STR(x) STRINGIZE(x) #define YES_NO(x) ((x) ? "yes" : "no") #define READ_CONFIG(x) (config & (x)) #define SET_CONFIG(x) \ config |= (x) #define CLEAR_CONFIG(x) \ config &= ~(x) #define LOOP_ACTION_CONFIG(f, x) \ f(x); \ continue /* macros: definitions */ #ifndef SIZE_T_C # if defined(UINT64_MAX) && SIZE_MAX == UINT64_MAX # define SIZE_T_C(x) UINT64_C(x) # elif defined(UINT32_MAX) && SIZE_MAX == UINT32_MAX # define SIZE_T_C(x) UINT32_C(x) # else # define SIZE_T_C(x) ((size_t) x) # endif #endif #ifndef SIZE_MAX # define SIZE_MAX (~SIZE_T_C(0)) #endif #endif /* _COMMON_H */