#include <stdarg.h>
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include <stdlib.h>
#include <utils/utils.h>
int randint(int limit)
{
int r;
int divisor = RAND_MAX / (limit + 1);
do {
r = rand() / divisor;
} while (r > limit);
return r;
}
uint32_t round_up_pow2(uint32_t v)
{
v -= 1;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v += 1;
return v;
}
int num_digits_in_number(int num)
{
int digits = 0, n = ABS(num);
while (n > 0) {
digits++;
n /= 10;
}
return digits;
}
__format_printf(3, 4)
void hexdump(const void *p, size_t len, const char *fmt, ...)
{
size_t i;
va_list args;
char str[16 + 1] = {0};
const uint8_t *data = p;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
printf(" [%zu] =>\n 0000 %02x ", len, data[0]);
str[0] = isprint(data[0]) ? data[0] : '.';
for (i = 1; i < len; i++) {
if ((i & 0x0f) == 0) {
printf(" |%16s|", str);
printf("\n %04zu ", i);
} else if((i & 0x07) == 0) {
printf(" ");
}
printf("%02x ", data[i]);
str[i & 0x0f] = isprint(data[i]) ? data[i] : '.';
}
if ((i &= 0x0f) != 0) {
if (i <= 8) printf(" ");
while (i < 16) {
printf(" ");
str[i++] = ' ';
}
printf(" |%16s|", str);
} else {
printf(" |%16s|", str);
}
printf("\n");
}
#if (defined(_WIN32) || defined(_WIN64))
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdint.h>
typedef struct timeval {
long tv_sec;
long tv_usec;
} timeval;
int gettimeofday(struct timeval * tp, struct timezone * tzp)
{
static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
SYSTEMTIME system_time;
FILETIME file_time;
uint64_t time;
GetSystemTime( &system_time );
SystemTimeToFileTime( &system_time, &file_time );
time = ((uint64_t)file_time.dwLowDateTime ) ;
time += ((uint64_t)file_time.dwHighDateTime) << 32;
tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
return 0;
}
int add_iso8601_utc_datetime(char* buf, size_t size)
{
int r;
SYSTEMTIME utcTime;
GetSystemTime(&utcTime);
r = snprintf(buf, size, "%04d-%02d-%02dT%02d:%02d:%02dZ",
utcTime.wYear, utcTime.wMonth, utcTime.wDay,
utcTime.wHour, utcTime.wMinute, utcTime.wSecond);
return r;
}
#elif defined(__linux__) || defined(__APPLE__)
#include <sys/time.h>
#include <time.h>
int add_iso8601_utc_datetime(char *buf, size_t size)
{
time_t now;
struct tm timeinfo;
time(&now);
gmtime_r(&now, &timeinfo);
return strftime(buf, size, "%Y-%m-%dT%H:%M:%SZ", &timeinfo);
}
#elif defined(ARDUINO)
#ifndef _TIMEVAL_DEFINED
struct timeval {
long tv_sec; long tv_usec; };
#endif
#ifndef _TIMEZONE_DEFINED
struct timezone {
int tz_minuteswest; int tz_dsttime; };
#endif
int gettimeofday(struct timeval * tp, struct timezone * tzp)
{
ARG_UNUSED(tzp);
tp->tv_sec = micros() / 1000000;
tp->tv_usec = micros() % 1000000;
return 0;
}
int add_iso8601_utc_datetime(char* buf, size_t size) {
ARG_UNUSED(buf);
ARG_UNUSED(size);
return 0;
}
#elif defined(__ZEPHYR__)
#include <sys/time.h>
#elif defined(__BARE_METAL__)
#ifndef _TIMEVAL_DEFINED
struct timeval {
long tv_sec; long tv_usec; };
#endif
#ifndef _TIMEZONE_DEFINED
struct timezone {
int tz_minuteswest; int tz_dsttime; };
#endif
int gettimeofday(struct timeval * tp, struct timezone * tzp)
{
ARG_UNUSED(tzp);
tp->tv_sec = 0;
tp->tv_usec = 0;
return 0;
}
int add_iso8601_utc_datetime(char* buf, size_t size) {
ARG_UNUSED(buf);
ARG_UNUSED(size);
return 0;
}
#else
#error Platform test failed
#endif
tick_t usec_now()
{
uint64_t usec;
struct timeval tv;
gettimeofday(&tv, NULL);
usec = tv.tv_sec * 1000LL * 1000LL + tv.tv_usec;
return (tick_t)usec;
}
void get_time(uint32_t *seconds, uint32_t *micro_seconds)
{
struct timeval tv;
gettimeofday(&tv, NULL);
*seconds = tv.tv_sec;
*micro_seconds = tv.tv_usec;
}
tick_t usec_since(tick_t last)
{
return usec_now() - last;
}
tick_t millis_now()
{
return (tick_t)(usec_now() / 1000U);
}
tick_t millis_since(tick_t last)
{
return millis_now() - last;
}
#if (defined(__linux__) || defined(__APPLE__)) && defined(__GLIBC__)
#include <execinfo.h>
void dump_trace(void)
{
char **strings;
size_t i, size;
void *array[1024];
size = backtrace(array, sizeof(array));
strings = backtrace_symbols(array, size);
for (i = 0; i < size; i++) {
printf("\t%s\n", strings[i]);
}
puts("");
free(strings);
}
#else
void dump_trace(void)
{
puts("Stack trace unavailable!\n");
}
#endif