notcurses_init(): interpret NULL as /dev/tty #571

This commit is contained in:
nick black 2020-05-08 22:33:39 -04:00
parent 05408f918c
commit d2c968b948
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
7 changed files with 29 additions and 12 deletions

View File

@ -13,6 +13,9 @@ rearrangements of Notcurses.
notcurses*` instead of a `struct ncplane`, as they create their own planes.
* `ncplane_set_channels()` and `ncplane_set_attr()` have been added to allow
`ncplane` attributes to be set directly and in toto.
* `NULL` can now be passed as the `FILE*` argument to `notcurses_init()` and
`ncdirect_init()`. In this case, a new `FILE*` will be created using
`/dev/tty`. If the `FILE*` cannot be created, an error will be returned.
* 1.3.4 (2020-05-07)
* `notcurses_lex_margins()` has been added to lex margins expressed in either

View File

@ -108,7 +108,8 @@ typedef struct notcurses_options {
int notcurses_lex_margins(const char* op, notcurses_options* opts);
// Initialize a notcurses context on the connected terminal at 'fp'. 'fp' must
// be a tty. You'll usually want stdout. Returns NULL on error, including any
// be a tty. You'll usually want stdout. NULL can be supplied for 'fp', in
// which case /dev/tty will be opened. Returns NULL on error, including any
// failure initializing terminfo.
struct notcurses* notcurses_init(const notcurses_options* opts, FILE* fp);

View File

@ -29,14 +29,16 @@ typedef struct notcurses_options {
# DESCRIPTION
**notcurses_init** prepares the **FILE** provided as **fp** (which must be
attached to a terminal) for cursor-addressable (multiline) mode. The
**notcurses_init** prepares the terminal for cursor-addressable (multiline)
mode. The **FILE** provided as **fp** must be writable and attached to a
terminal, or **NULL**. If it is **NULL**, **/dev/tty** will be opened. The
**struct notcurses_option** passed as **opts** controls behavior. Only one
instance should be associated with a given terminal at a time, though it is no
problem to have multiple instances in a given process. On success, a pointer to
a valid **struct notcurses** is returned. **NULL** is returned on failure.
Before the process exits, **notcurses_stop(3)** should be called to reset the
terminal and free up resources.
problem to have multiple instances in a given process.
On success, a pointer to a valid **struct notcurses** is returned. **NULL** is
returned on failure. Before the process exits, **notcurses_stop(3)** should be
called to reset the terminal and free up resources.
An appropriate **terminfo(5)** entry must exist for the terminal. This entry is
usually selected using the value of the **TERM** environment variable (see

View File

@ -793,7 +793,8 @@ typedef struct notcurses_options {
API int notcurses_lex_margins(const char* op, notcurses_options* opts);
// Initialize a notcurses context on the connected terminal at 'fp'. 'fp' must
// be a tty. You'll usually want stdout. Returns NULL on error, including any
// be a tty. You'll usually want stdout. NULL can be supplied for 'fp', in
// which case /dev/tty will be opened. Returns NULL on error, including any
// failure initializing terminfo.
API struct notcurses* notcurses_init(const notcurses_options* opts, FILE* fp);

View File

@ -447,7 +447,7 @@ int main(int argc, char** argv){
struct timespec starttime;
clock_gettime(CLOCK_MONOTONIC, &starttime);
struct notcurses* nc;
if((nc = notcurses_init(&nopts, stdout)) == NULL){
if((nc = notcurses_init(&nopts, NULL)) == NULL){
return EXIT_FAILURE;
}
if(notcurses_mouse_enable(nc)){

View File

@ -332,6 +332,7 @@ typedef struct notcurses {
palette256 palette; // 256-indexed palette can be used instead of/with RGB
bool palette_damage[NCPALETTESIZE];
struct esctrie* inputescapes; // trie of input escapes -> ncspecial_keys
bool ownttyfp; // do we own ttyfp (and thus must close it?)
} notcurses;
void sigwinch_handler(int signo);

View File

@ -815,9 +815,6 @@ ncdirect* ncdirect_init(const char* termtype, FILE* outfp){
}
notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
if(outfp == NULL){
outfp = stdout;
}
notcurses_options defaultopts;
memset(&defaultopts, 0, sizeof(defaultopts));
if(!opts){
@ -838,6 +835,14 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
if(ret == NULL){
return ret;
}
bool own_outfp = false;
if(outfp == NULL){
if((outfp = fopen("/dev/tty", "wbe")) == NULL){
free(ret);
return NULL;
}
own_outfp = true;
}
ret->margin_t = opts->margin_t;
ret->margin_b = opts->margin_b;
ret->margin_l = opts->margin_l;
@ -847,6 +852,7 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
reset_stats(&ret->stats);
reset_stats(&ret->stashstats);
ret->ttyfp = outfp;
ret->ownttyfp = own_outfp;
ret->renderfp = opts->renderfp;
ret->inputescapes = NULL;
ret->ttyinfp = stdin; // FIXME
@ -1007,6 +1013,9 @@ int notcurses_stop(notcurses* nc){
free(nc->rstate.mstream);
input_free_esctrie(&nc->inputescapes);
stash_stats(nc);
if(nc->ownttyfp){
ret |= fclose(nc->ttyfp);
}
if(!nc->suppress_banner){
if(nc->stashstats.renders){
char totalbuf[BPREFIXSTRLEN + 1];