mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
Introduce src/compat/ for all bins
I've created the new files src/compat/compat.{hc}. These are available to all binaries by adding src to the include directories, and src/compat/compat.c to the sources. Several functions are implemented here which one or more target operating systems are missing, right now all related to time. This includes clock_nanosleep(), which is missing on OS X and DragonFly BSD. Eliminate the other three definitions of timespec_to_ns() and friends. Standardize on NANOSECS_IN_SEC rather than the more opaque GIG. Progress on #1121.
This commit is contained in:
parent
e7d0b186ea
commit
8283adc28f
@ -115,9 +115,11 @@ set_property(GLOBAL APPEND PROPERTY PACKAGES_FOUND qrcodegen)
|
||||
endif()
|
||||
find_library(LIBRT rt)
|
||||
|
||||
file(GLOB COMPATSRC CONFIGURE_DEPENDS src/compat/compat.c)
|
||||
|
||||
# libnotcurses (core shared library, core static library)
|
||||
file(GLOB NCSRCS CONFIGURE_DEPENDS src/lib/*.c src/lib/*.cpp)
|
||||
add_library(notcurses SHARED ${NCSRCS})
|
||||
add_library(notcurses SHARED ${NCSRCS} ${COMPATSRC})
|
||||
if(${USE_STATIC})
|
||||
add_library(notcurses-static STATIC ${NCSRCS})
|
||||
else()
|
||||
@ -140,6 +142,7 @@ set_target_properties(notcurses-static PROPERTIES
|
||||
target_include_directories(notcurses
|
||||
PRIVATE
|
||||
include
|
||||
src
|
||||
"${PROJECT_BINARY_DIR}/include"
|
||||
"${TERMINFO_INCLUDE_DIRS}"
|
||||
"${READLINE_INCLUDE_DIRS}"
|
||||
@ -147,6 +150,7 @@ target_include_directories(notcurses
|
||||
target_include_directories(notcurses-static
|
||||
PRIVATE
|
||||
include
|
||||
src
|
||||
"${PROJECT_BINARY_DIR}/include"
|
||||
"${TERMINFO_STATIC_INCLUDE_DIRS}"
|
||||
"${READLINE_STATIC_INCLUDE_DIRS}"
|
||||
@ -379,6 +383,7 @@ target_compile_definitions(notcurses-demo
|
||||
target_include_directories(notcurses-demo
|
||||
PRIVATE
|
||||
include
|
||||
src
|
||||
"${PROJECT_BINARY_DIR}/include"
|
||||
PUBLIC
|
||||
"${AVCODEC_INCLUDE_DIRS}"
|
||||
@ -400,7 +405,7 @@ foreach(f ${POCSRCS})
|
||||
get_filename_component(fe "${f}" NAME_WE)
|
||||
add_executable(${fe} ${f})
|
||||
target_include_directories(${fe}
|
||||
PRIVATE include "${TERMINFO_INCLUDE_DIRS}"
|
||||
PRIVATE include src "${TERMINFO_INCLUDE_DIRS}"
|
||||
"${PROJECT_BINARY_DIR}/include"
|
||||
)
|
||||
target_link_libraries(${fe}
|
||||
@ -548,6 +553,7 @@ add_executable(notcurses-view ${VIEWSRCS})
|
||||
target_include_directories(notcurses-view
|
||||
PRIVATE
|
||||
include
|
||||
src
|
||||
"${PROJECT_BINARY_DIR}/include"
|
||||
)
|
||||
target_link_libraries(notcurses-view
|
||||
@ -565,6 +571,7 @@ add_executable(notcurses-tester ${TESTSRCS})
|
||||
target_include_directories(notcurses-tester
|
||||
PRIVATE
|
||||
include
|
||||
src
|
||||
"${PROJECT_BINARY_DIR}/include"
|
||||
src/lib
|
||||
)
|
||||
|
28
src/compat/compat.c
Normal file
28
src/compat/compat.c
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef __linux__
|
||||
#ifndef __FreeBSD__
|
||||
#include <time.h>
|
||||
// clock_nanosleep is unavailable on DragonFly BSD and Mac OS X
|
||||
int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *request,
|
||||
struct timespec *remain){
|
||||
struct timespec now;
|
||||
if(clock_gettime(clockid, &now)){
|
||||
return -1;
|
||||
}
|
||||
uint64_t nowns = timespec_to_ns(&now);
|
||||
uint64_t targns = timespec_to_ns(&request);
|
||||
if(flags != TIMER_ABSTIME){
|
||||
targns += nowns;
|
||||
}
|
||||
if(nowns < targns){
|
||||
uint64_t waitns = targns - nowns;
|
||||
struct timespec waitts = {
|
||||
.tv_sec = waitns / 1000000000,
|
||||
.tv_nsec = waitns % 1000000000,
|
||||
};
|
||||
return nanosleep(&waitts, remain);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
27
src/compat/compat.h
Normal file
27
src/compat/compat.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef NOTCURSES_COMPAT
|
||||
#define NOTCURSES_COMPAT
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#define NANOSECS_IN_SEC 1000000000ul
|
||||
|
||||
static inline uint64_t
|
||||
timespec_to_ns(const struct timespec* ts){
|
||||
return ts->tv_sec * NANOSECS_IN_SEC + ts->tv_nsec;
|
||||
}
|
||||
|
||||
static inline struct timespec*
|
||||
ns_to_timespec(uint64_t ns, struct timespec* ts){
|
||||
ts->tv_sec = ns / NANOSECS_IN_SEC;
|
||||
ts->tv_nsec = ns % NANOSECS_IN_SEC;
|
||||
return ts;
|
||||
}
|
||||
|
||||
// compatibility wrappers for code available only on certain operating systems.
|
||||
// this file is not installed, but only consumed during compilation. if we're
|
||||
// on an operating system which implements a given function, it won't be built.
|
||||
int clock_nanosleep(clockid_t clockid, int flags,
|
||||
const struct timespec *request,
|
||||
struct timespec *remain);
|
||||
|
||||
#endif
|
@ -332,9 +332,9 @@ handle_opts(int argc, char** argv, notcurses_options* opts,
|
||||
usage(*argv, EXIT_FAILURE);
|
||||
}
|
||||
delaymultiplier = f;
|
||||
uint64_t ns = f * GIG;
|
||||
demodelay.tv_sec = ns / GIG;
|
||||
demodelay.tv_nsec = ns % GIG;
|
||||
uint64_t ns = f * NANOSECS_IN_SEC;
|
||||
demodelay.tv_sec = ns / NANOSECS_IN_SEC;
|
||||
demodelay.tv_nsec = ns % NANOSECS_IN_SEC;
|
||||
break;
|
||||
}default:
|
||||
usage(*argv, EXIT_FAILURE);
|
||||
@ -424,15 +424,15 @@ summary_table(struct ncdirect* nc, const char* spec, bool canimage, bool canvide
|
||||
uint64_t nsdelta = 0;
|
||||
for(size_t i = 0 ; i < strlen(spec) ; ++i){
|
||||
nsdelta += results[i].timens;
|
||||
qprefix(results[i].timens, GIG, timebuf, 0);
|
||||
qprefix(results[i].stats.render_ns, GIG, rtimebuf, 0);
|
||||
qprefix(results[i].timens, NANOSECS_IN_SEC, timebuf, 0);
|
||||
qprefix(results[i].stats.render_ns, NANOSECS_IN_SEC, rtimebuf, 0);
|
||||
bprefix(results[i].stats.render_bytes, 1, totalbuf, 0);
|
||||
if(results[i].stats.renders){
|
||||
qprefix((uintmax_t)results[i].stats.renders * GIG * 1000 /
|
||||
qprefix((uintmax_t)results[i].stats.renders * NANOSECS_IN_SEC * 1000 /
|
||||
(results[i].stats.render_ns + results[i].stats.writeout_ns),
|
||||
1000, tfpsbuf, 0);
|
||||
}else{
|
||||
qprefix(0, GIG, tfpsbuf, 0);
|
||||
qprefix(0, NANOSECS_IN_SEC, tfpsbuf, 0);
|
||||
}
|
||||
uint32_t rescolor;
|
||||
if(results[i].result < 0){
|
||||
@ -455,7 +455,7 @@ summary_table(struct ncdirect* nc, const char* spec, bool canimage, bool canvide
|
||||
PREFIXFMT(timebuf), (uintmax_t)(results[i].stats.renders),
|
||||
BPREFIXFMT(totalbuf), PREFIXFMT(rtimebuf),
|
||||
results[i].timens ?
|
||||
results[i].stats.renders / ((double)results[i].timens / GIG) : 0.0,
|
||||
results[i].stats.renders / ((double)results[i].timens / NANOSECS_IN_SEC) : 0.0,
|
||||
(uintmax_t)(results[i].timens ?
|
||||
results[i].stats.render_ns * 100 / results[i].timens : 0),
|
||||
(uintmax_t)(results[i].timens ?
|
||||
@ -473,16 +473,16 @@ summary_table(struct ncdirect* nc, const char* spec, bool canimage, bool canvide
|
||||
totalrenderns += results[i].stats.render_ns;
|
||||
totalwriteoutns += results[i].stats.writeout_ns;
|
||||
}
|
||||
qprefix(nsdelta, GIG, timebuf, 0);
|
||||
qprefix(nsdelta, NANOSECS_IN_SEC, timebuf, 0);
|
||||
bprefix(totalbytes, 1, totalbuf, 0);
|
||||
qprefix(totalrenderns, GIG, rtimebuf, 0);
|
||||
qprefix(totalrenderns, NANOSECS_IN_SEC, rtimebuf, 0);
|
||||
table_segment(nc, "", "══╧════════╧════════╪═══════╪═════════╪═════════╪═══════╪══╧══╧═══════╝\n");
|
||||
printf(" ");
|
||||
table_printf(nc, "│", "%*ss", PREFIXFMT(timebuf));
|
||||
table_printf(nc, "│", "%7lu", totalframes);
|
||||
table_printf(nc, "│", "%*s", BPREFIXFMT(totalbuf));
|
||||
table_printf(nc, "│", " %*ss", PREFIXFMT(rtimebuf));
|
||||
table_printf(nc, "│", "%7.1f", nsdelta ? totalframes / ((double)nsdelta / GIG) : 0);
|
||||
table_printf(nc, "│", "%7.1f", nsdelta ? totalframes / ((double)nsdelta / NANOSECS_IN_SEC) : 0);
|
||||
printf("\n");
|
||||
ncdirect_set_fg_rgb8(nc, 0xff, 0xb0, 0xb0);
|
||||
fflush(stdout); // in case we print to stderr below, we want color from above
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <notcurses/notcurses.h>
|
||||
#include <builddef.h>
|
||||
#include <version.h>
|
||||
#include "compat/compat.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -88,20 +89,7 @@ demo_getc_blocking(struct notcurses* nc, ncinput* ni){
|
||||
/*----------------------------- end demo input API -------------------------*/
|
||||
|
||||
/*-------------------------------time helpers----------------------------*/
|
||||
#define GIG 1000000000ul
|
||||
#define MAXSLEEP (GIG / 80) // nanoseconds
|
||||
|
||||
static inline uint64_t
|
||||
timespec_to_ns(const struct timespec* ts){
|
||||
return ts->tv_sec * GIG + ts->tv_nsec;
|
||||
}
|
||||
|
||||
static inline struct timespec*
|
||||
ns_to_timespec(uint64_t ns, struct timespec* ts){
|
||||
ts->tv_sec = ns / GIG;
|
||||
ts->tv_nsec = ns % GIG;
|
||||
return ts;
|
||||
}
|
||||
#define MAXSLEEP (NANOSECS_IN_SEC / 80) // nanoseconds
|
||||
|
||||
static inline int64_t
|
||||
timespec_subtract_ns(const struct timespec* time1, const struct timespec* time0){
|
||||
@ -130,8 +118,8 @@ static inline void
|
||||
timespec_div(const struct timespec* ts, unsigned divisor, struct timespec* quots){
|
||||
uint64_t ns = timespec_to_ns(ts);
|
||||
ns /= divisor;
|
||||
quots->tv_nsec = ns % GIG;
|
||||
quots->tv_sec = ns / GIG;
|
||||
quots->tv_nsec = ns % NANOSECS_IN_SEC;
|
||||
quots->tv_sec = ns / NANOSECS_IN_SEC;
|
||||
}
|
||||
|
||||
// divide the provided timespec 'ts' by 'multiplier' into 'product'
|
||||
@ -139,8 +127,8 @@ static inline void
|
||||
timespec_mul(const struct timespec* ts, unsigned multiplier, struct timespec* product){
|
||||
uint64_t ns = timespec_to_ns(ts);
|
||||
ns *= multiplier;
|
||||
product->tv_nsec = ns % GIG;
|
||||
product->tv_sec = ns / GIG;
|
||||
product->tv_nsec = ns % NANOSECS_IN_SEC;
|
||||
product->tv_sec = ns / NANOSECS_IN_SEC;
|
||||
}
|
||||
/*-------------------------------time helpers----------------------------*/
|
||||
|
||||
|
@ -374,8 +374,8 @@ hud_print_finished(elem* list){
|
||||
if(ncplane_printf_yx(hud, line, 1, "%d", e->frames) < 0){
|
||||
return -1;
|
||||
}
|
||||
if(ncplane_printf_yx(hud, line, 7, "%ju.%03jus", e->totalns / GIG,
|
||||
(e->totalns % GIG) / 1000000) < 0){
|
||||
if(ncplane_printf_yx(hud, line, 7, "%ju.%03jus", e->totalns / NANOSECS_IN_SEC,
|
||||
(e->totalns % NANOSECS_IN_SEC) / 1000000) < 0){
|
||||
return -1;
|
||||
}
|
||||
if(ncplane_putstr_yx(hud, line, 16, e->name) < 0){
|
||||
@ -516,7 +516,7 @@ demo_nanosleep_abstime_ns(struct notcurses* nc, uint64_t deadline){
|
||||
while(deadline > timespec_to_ns(&now)){
|
||||
fsleep.tv_sec = 0;
|
||||
fsleep.tv_nsec = MAXSLEEP;
|
||||
if(deadline - timespec_to_ns(&now) < GIG / 100){
|
||||
if(deadline - timespec_to_ns(&now) < NANOSECS_IN_SEC / 100){
|
||||
fsleep.tv_nsec = deadline - timespec_to_ns(&now);
|
||||
}
|
||||
ncinput ni;
|
||||
@ -565,7 +565,7 @@ int demo_render(struct notcurses* nc){
|
||||
if(!plot_hidden){
|
||||
ncplane_move_top(ncuplot_plane(plot));
|
||||
}
|
||||
uint64_t ns = (timespec_to_ns(&ts) - plottimestart) / (GIG / FPSHZ);
|
||||
uint64_t ns = (timespec_to_ns(&ts) - plottimestart) / (NANOSECS_IN_SEC / FPSHZ);
|
||||
ncuplot_add_sample(plot, ns, 1);
|
||||
}
|
||||
if(menu){
|
||||
@ -588,8 +588,8 @@ int demo_render(struct notcurses* nc){
|
||||
if(ncplane_printf_yx(hud, 1, 1, "%d", elems->frames) < 0){
|
||||
return -1;
|
||||
}
|
||||
if(ncplane_printf_yx(hud, 1, 7, "%ju.%03jus", ns / GIG,
|
||||
(ns % GIG) / 1000000) < 0){
|
||||
if(ncplane_printf_yx(hud, 1, 7, "%ju.%03jus", ns / NANOSECS_IN_SEC,
|
||||
(ns % NANOSECS_IN_SEC) / 1000000) < 0){
|
||||
return -1;
|
||||
}
|
||||
if(ncplane_putstr_yx(hud, 1, 16, elems->name) < 0){
|
||||
|
@ -26634,7 +26634,7 @@ int jungle_demo(struct notcurses* nc){
|
||||
free(buf);
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
|
||||
int iter = 0;
|
||||
int64_t iterns = GIG / 30;
|
||||
int64_t iterns = NANOSECS_IN_SEC / 30;
|
||||
int64_t nsrunning;
|
||||
do{
|
||||
DEMO_RENDER(nc);
|
||||
|
@ -59,7 +59,7 @@ play(struct notcurses* nc, struct ncplane** chunks){
|
||||
int lastdir = -1;
|
||||
for(m = 0 ; m < MOVES ; ++m){
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur);
|
||||
uint64_t now = cur.tv_sec * GIG + cur.tv_nsec;
|
||||
uint64_t now = cur.tv_sec * NANOSECS_IN_SEC + cur.tv_nsec;
|
||||
if(now >= deadline_ns){
|
||||
break;
|
||||
}
|
||||
@ -189,7 +189,7 @@ int sliding_puzzle_demo(struct notcurses* nc){
|
||||
goto done;
|
||||
}
|
||||
DEMO_RENDER(nc);
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = GIG, };
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = NANOSECS_IN_SEC, };
|
||||
// fade out each of the chunks in succession
|
||||
/*for(cy = 0 ; cy < CHUNKS_VERT ; ++cy){
|
||||
for(cx = 0 ; cx < CHUNKS_HORZ ; ++cx){
|
||||
|
@ -210,7 +210,7 @@ message(struct ncplane* n, int maxy, int maxx, int num, int total,
|
||||
ncplane_printf_yx(n, 1, 4, " %03dx%03d (%d/%d) ", maxx, maxy, num + 1, total);
|
||||
ncplane_off_styles(n, NCSTYLE_ITALIC);
|
||||
ncplane_set_fg_rgb8(n, 224, 128, 224);
|
||||
ncplane_putstr_yx(n, 3, 1, " 🔥 unicode 13, resize awareness, 24b truecolor…🔥 ");
|
||||
ncplane_putstr_yx(n, 3, 1, " 🎆🔥 unicode 13, resize awareness, 24b truecolor…🔥🎆 ");
|
||||
ncplane_set_fg_rgb8(n, 255, 255, 255);
|
||||
return 0;
|
||||
}
|
||||
@ -555,8 +555,8 @@ int witherworm_demo(struct notcurses* nc){
|
||||
uint64_t delay = timespec_to_ns(&demodelay);
|
||||
delay /= screens;
|
||||
struct timespec tv;
|
||||
if(delay > GIG){
|
||||
ns_to_timespec(GIG, &tv);
|
||||
if(delay > NANOSECS_IN_SEC){
|
||||
ns_to_timespec(NANOSECS_IN_SEC, &tv);
|
||||
}else{
|
||||
ns_to_timespec(delay, &tv);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ const char* oiio_version(void);
|
||||
#include <langinfo.h>
|
||||
#include <netinet/in.h>
|
||||
#include "notcurses/notcurses.h"
|
||||
#include "compat/compat.h"
|
||||
#include "egcpool.h"
|
||||
|
||||
struct esctrie;
|
||||
@ -606,20 +607,6 @@ ncplane_cell_ref_yx(ncplane* n, int y, int x){
|
||||
return &n->fb[nfbcellidx(n, y, x)];
|
||||
}
|
||||
|
||||
#define NANOSECS_IN_SEC 1000000000
|
||||
|
||||
static inline uint64_t
|
||||
timespec_to_ns(const struct timespec* t){
|
||||
return t->tv_sec * NANOSECS_IN_SEC + t->tv_nsec;
|
||||
}
|
||||
|
||||
static inline struct timespec*
|
||||
ns_to_timespec(uint64_t ns, struct timespec* ts){
|
||||
ts->tv_sec = ns / NANOSECS_IN_SEC;
|
||||
ts->tv_nsec = ns % NANOSECS_IN_SEC;
|
||||
return ts;
|
||||
}
|
||||
|
||||
static inline void
|
||||
cell_debug(const egcpool* p, const nccell* c){
|
||||
fprintf(stderr, "gcluster: %u %s style: 0x%04x chan: 0x%016jx\n",
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include <notcurses/notcurses.h>
|
||||
#include "compat/compat.h"
|
||||
|
||||
int main(int argc, char** argv){
|
||||
if(setlocale(LC_ALL, "") == NULL){
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <locale.h>
|
||||
#include <notcurses/notcurses.h>
|
||||
#include "compat/compat.h"
|
||||
|
||||
int main(void){
|
||||
setlocale(LC_ALL, "");
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <notcurses/notcurses.h>
|
||||
#include "compat/compat.h"
|
||||
|
||||
static int
|
||||
rotate_grad(struct notcurses* nc){
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <cassert>
|
||||
#include <unistd.h>
|
||||
#include <notcurses/notcurses.h>
|
||||
#include "compat/compat.h"
|
||||
|
||||
int main(int argc, char** argv){
|
||||
struct timespec ts = {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <iostream>
|
||||
#include <ncpp/Visual.hh>
|
||||
#include <ncpp/NotCurses.hh>
|
||||
#include "compat/compat.h"
|
||||
|
||||
using namespace ncpp;
|
||||
|
||||
@ -31,20 +32,6 @@ void usage(std::ostream& o, const char* name, int exitcode){
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
constexpr auto NANOSECS_IN_SEC = 1000000000ll;
|
||||
|
||||
static inline auto
|
||||
timespec_to_ns(const struct timespec* ts) -> uint64_t {
|
||||
return ts->tv_sec * NANOSECS_IN_SEC + ts->tv_nsec;
|
||||
}
|
||||
|
||||
static inline struct timespec*
|
||||
ns_to_timespec(uint64_t ns, struct timespec* ts){
|
||||
ts->tv_sec = ns / NANOSECS_IN_SEC;
|
||||
ts->tv_nsec = ns % NANOSECS_IN_SEC;
|
||||
return ts;
|
||||
}
|
||||
|
||||
struct marshal {
|
||||
struct ncplane* subtitle_plane;
|
||||
int framecount;
|
||||
|
Loading…
x
Reference in New Issue
Block a user