libncurses: Import https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.5.tar.gz changes

Change-Id: I3433d30ca01359fd2e3623ede96b531f0b39cbfa
Signed-off-by: micky387 <mickaelsaibi@free.fr>
diff --git a/test/sp_tinfo.c b/test/sp_tinfo.c
new file mode 100644
index 0000000..72b20cf
--- /dev/null
+++ b/test/sp_tinfo.c
@@ -0,0 +1,359 @@
+/****************************************************************************
+ * Copyright 2019-2022,2023 Thomas E. Dickey                                *
+ * Copyright 2017 Free Software Foundation, Inc.                            *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * $Id: sp_tinfo.c,v 1.29 2023/06/24 14:14:56 tom Exp $
+ *
+ * TOTO: add option for non-sp-funcs interface
+ */
+
+#define USE_TINFO
+#include <test.priv.h>
+
+#if HAVE_TPUTS_SP
+/*
+ * The higher-level curses library stores a TERMINAL* inside SCREEN, but the
+ * latter is opaque.  This structure helps us keep the two associated.
+ */
+typedef struct {
+    const char *name;
+    FILE *fp;
+    SCREEN *sp;
+    TERMINAL *term;
+    int (*outc) (SCREEN *, int);
+} MYDATA;
+
+static bool opt_n = FALSE;	/* true to suppress new_prescr */
+static bool opt_t = FALSE;	/* true to use termcap */
+
+static int
+my_outc(SCREEN *sp, int ch)
+{
+    (void) sp;
+    return fputc(ch, stdout);
+}
+
+static int
+my_errc(SCREEN *sp, int ch)
+{
+    (void) sp;
+    return fputc(ch, stderr);
+}
+
+static MYDATA *
+initialize(const char *name, FILE *output)
+{
+    MYDATA *result = typeCalloc(MYDATA, 1);
+    int error;
+
+    result->fp = output;
+    result->name = name;
+    result->outc = (fileno(output) == 1) ? my_outc : my_errc;
+    result->sp = opt_n ? NULL : new_prescr();
+
+    if (opt_t) {
+	char *temp = strdup(name);
+	tgetent_sp(result->sp, temp, name);
+	free(temp);
+    } else {
+	setupterm((NCURSES_CONST char *) name, fileno(output), &error);
+    }
+    result->term = cur_term;
+
+    return result;
+}
+
+static void
+show_flag(MYDATA * data, const char *name, int value)
+{
+    if (value < 0) {
+	fprintf(data->fp, " %s = (unknown)\n", name);
+    } else if (value == 0) {
+	fprintf(data->fp, " %s = false\n", name);
+    } else {
+	fprintf(data->fp, " %s = true\n", name);
+    }
+}
+
+#define TC_PARMS data->sp, (NCURSES_CONST char *)tc
+#define TI_PARMS data->sp, (NCURSES_CONST char *)ti
+
+static void
+show_cap_flag(MYDATA * data, const char *ti, const char *tc)
+{
+    const char *name = (opt_t ? tc : ti);
+    show_flag(data, name, (opt_t
+			   ? tgetflag_sp(TC_PARMS)
+			   : tigetflag_sp(TI_PARMS)));
+}
+
+static void
+show_number(MYDATA * data, const char *name, int value)
+{
+    if (value <= -2) {
+	fprintf(data->fp, " %s = (unknown)\n", name);
+    } else if (value <= -1) {
+	fprintf(data->fp, " %s = (missing)\n", name);
+    } else {
+	fprintf(data->fp, " %s = %d\n", name, value);
+    }
+}
+
+static void
+show_cap_number(MYDATA * data, const char *ti, const char *tc)
+{
+    const char *name = (opt_t ? tc : ti);
+    show_number(data, name, (opt_t
+			     ? tgetnum_sp(TC_PARMS)
+			     : tigetnum_sp(TI_PARMS)));
+}
+
+static void
+show_string(MYDATA * data, const char *name, const char *value)
+{
+    fprintf(data->fp, " %s = ", name);
+    if (value == 0) {
+	fprintf(data->fp, "(missing)");
+    } else if (value == (char *) -1) {
+	fprintf(data->fp, "(canceled)");
+    } else {
+	int ch;
+	while ((ch = UChar(*value++)) != '\0') {
+	    if (ch < 32) {
+		fprintf(data->fp, "^%c", ch | '@');
+	    } else if (ch == 127) {
+		fprintf(data->fp, "^?");
+	    } else if (ch > 127) {
+		fprintf(data->fp, "\\%03o", ch);
+	    } else {
+		fprintf(data->fp, "%c", ch);
+	    }
+	}
+    }
+    fprintf(data->fp, "\n");
+}
+
+static void
+show_cap_string(MYDATA * data, const char *ti, const char *tc)
+{
+    const char *name = (opt_t ? tc : ti);
+    char tcapjunk[1024];
+    char *tcap_ptr = tcapjunk;
+    show_string(data, name, (opt_t
+			     ? tgetstr_sp(TC_PARMS, &tcap_ptr)
+			     : tigetstr_sp(TI_PARMS)));
+}
+
+static void
+show_char(MYDATA * data, const char *name, int value)
+{
+    if (value < 0) {
+	show_string(data, name, "(missing)");
+    } else {
+	char temp[2];
+	temp[0] = (char) value;
+	temp[1] = '\0';
+	show_string(data, name, temp);
+    }
+}
+
+static void
+do_stuff(MYDATA * data)
+{
+    SCREEN *sp = data->sp;
+#if NCURSES_EXT_FUNCS
+    char *s;
+    int my_code = 1234;
+    const char *my_text = "\033[?m";
+#endif
+
+    set_curterm_sp(sp, data->term);
+
+    /* putp always goes to standard output */
+    putp_sp(sp, "Hello ");
+    putp_sp(sp, data->name);
+    putp_sp(sp, "!\n");
+
+    fprintf(data->fp, "Term: %s\n", termname_sp(sp));
+    fprintf(data->fp, "Long: %s\n", longname_sp(sp));
+    show_cap_flag(data, "am", "am");
+    show_cap_number(data, "lines", "li");
+    show_cap_string(data, "clear", "cl");
+    show_cap_string(data, "tbc", "ct");
+    show_flag(data, "has_ic", has_ic_sp(sp));
+    show_flag(data, "has_il", has_il_sp(sp));
+    show_number(data, "baudrate", baudrate_sp(sp));
+    show_char(data, "erase ch", erasechar_sp(sp));
+    show_char(data, "kill ch", killchar_sp(sp));
+    show_string(data, "unctrl", unctrl_sp(sp, 033));
+    fflush(data->fp);
+
+#if NCURSES_EXT_FUNCS
+    define_key_sp(sp, my_text, my_code);
+    has_key_sp(sp, 0);
+    key_defined_sp(sp, my_text);
+    if ((s = keybound_sp(sp, my_code, 0)) != 0)
+	free(s);
+#endif
+    keyname_sp(sp, '?');
+#if NCURSES_EXT_FUNCS
+    keyok_sp(sp, my_code, FALSE);
+    keyok_sp(sp, my_code, TRUE);
+#endif
+
+    savetty_sp(sp);
+
+    def_shell_mode_sp(sp);
+
+    /*
+     * These functions are low-level settings for ncurses.
+     */
+#if NCURSES_EXT_FUNCS
+    set_tabsize_sp(sp, 5);	/* waddch */
+#endif
+    typeahead_sp(sp, FALSE);	/* waddch */
+    use_env_sp(sp, FALSE);	/* newterm */
+    use_tioctl_sp(sp, FALSE);	/* newterm */
+    intrflush_sp(sp, 0, 0);	/* wgetch */
+    flushinp_sp(sp);		/* waddch */
+    halfdelay_sp(sp, 5);	/* wgetch */
+
+    /*
+     * These manipulate the terminal modes, mainly for wgetch.
+     */
+    cbreak_sp(sp);
+    raw_sp(sp);
+    def_prog_mode_sp(sp);
+
+    delay_output_sp(sp, 200);
+
+    napms_sp(sp, 10);
+
+    nocbreak_sp(sp);
+    noqiflush_sp(sp);
+    noraw_sp(sp);
+    qiflush_sp(sp);
+
+    resetty_sp(sp);
+
+    tputs_sp(sp, "{reset-mode}\n", 0, data->outc);
+
+    reset_prog_mode_sp(sp);
+
+    curs_set_sp(sp, 0);
+    tputs_sp(sp, "{prog-mode}\n", 0, data->outc);
+
+    reset_shell_mode_sp(sp);
+
+    tputs_sp(sp, "{shell-mode}\n", 0, data->outc);
+}
+
+static void
+cleanup(MYDATA * data)
+{
+    set_curterm(data->term);
+    del_curterm(data->term);
+    free(data);
+}
+
+static void
+usage(int ok)
+{
+    static const char *tbl[] =
+    {
+	"Usage: sp_tinfo [output] [error]"
+	,""
+	,USAGE_COMMON
+	,"Options:"
+	," -n       suppress call to new_prescr()"
+	," -t       use termcap functions rather than terminfo"
+    };
+    size_t n;
+    for (n = 0; n < SIZEOF(tbl); ++n) {
+	fprintf(stderr, "%s\n", tbl[n]);
+    }
+    ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+/* *INDENT-OFF* */
+VERSION_COMMON()
+/* *INDENT-ON* */
+
+int
+main(int argc, char *argv[])
+{
+    MYDATA *my_out;
+    MYDATA *my_err;
+    int ch;
+
+    while ((ch = getopt(argc, argv, OPTS_COMMON "nt")) != -1) {
+	switch (ch) {
+	case 'n':
+	    opt_n = TRUE;
+	    break;
+	case 't':
+	    opt_t = TRUE;
+	    break;
+	case OPTS_VERSION:
+	    show_version(argv);
+	    ExitProgram(EXIT_SUCCESS);
+	default:
+	    usage(ch == OPTS_USAGE);
+	    /* NOTREACHED */
+	}
+    }
+    argv += (optind - 1);
+    argc -= (optind - 1);
+
+    if (argc > 3)
+	usage(FALSE);
+
+    my_out = initialize((argc > 1) ? argv[1] : "vt100", stdout);
+    my_err = initialize((argc > 2) ? argv[2] : "ansi", stderr);
+
+    do_stuff(my_out);
+    do_stuff(my_err);
+
+    if (my_out != my_err) {
+	cleanup(my_out);
+	cleanup(my_err);
+    } else {
+	cleanup(my_out);
+    }
+
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    fprintf(stderr,
+	    "This program requires the low-level ncurses sp-funcs tputs_sp\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif