aboutsummaryrefslogtreecommitdiff
path: root/ncurses/tinfo/lib_tparm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ncurses/tinfo/lib_tparm.c')
-rw-r--r--ncurses/tinfo/lib_tparm.c120
1 files changed, 93 insertions, 27 deletions
diff --git a/ncurses/tinfo/lib_tparm.c b/ncurses/tinfo/lib_tparm.c
index 439115b01e83..a98cfd86afbf 100644
--- a/ncurses/tinfo/lib_tparm.c
+++ b/ncurses/tinfo/lib_tparm.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2018,2019 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 *
@@ -42,7 +42,7 @@
#include <ctype.h>
#include <tic.h>
-MODULE_ID("$Id: lib_tparm.c,v 1.90 2013/11/09 14:53:05 tom Exp $")
+MODULE_ID("$Id: lib_tparm.c,v 1.107 2019/01/19 15:46:25 tom Exp $")
/*
* char *
@@ -253,6 +253,9 @@ parse_format(const char *s, char *format, int *len)
case 'x': /* FALLTHRU */
case 'X': /* FALLTHRU */
case 's':
+#ifdef EXP_XTERM_1005
+ case 'u':
+#endif
*format++ = *s;
done = TRUE;
break;
@@ -323,6 +326,7 @@ parse_format(const char *s, char *format, int *len)
#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
+#define tc_BUMP() if (level < 0 && number < 2) number++
/*
* Analyze the string to see how many parameters we need from the varargs list,
@@ -343,14 +347,15 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
int lastpop = -1;
int len;
int number = 0;
+ int level = -1;
const char *cp = string;
static char dummy[] = "";
if (cp == 0)
return 0;
- if ((len2 = strlen(cp)) > TPS(fmt_size)) {
- TPS(fmt_size) = len2 + TPS(fmt_size) + 2;
+ if ((len2 = strlen(cp)) + 2 > TPS(fmt_size)) {
+ TPS(fmt_size) += len2 + 2;
TPS(fmt_buff) = typeRealloc(char, TPS(fmt_size), TPS(fmt_buff));
if (TPS(fmt_buff) == 0)
return 0;
@@ -372,22 +377,30 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
case 'x': /* FALLTHRU */
case 'X': /* FALLTHRU */
case 'c': /* FALLTHRU */
- if (lastpop <= 0)
- number++;
+#ifdef EXP_XTERM_1005
+ case 'u':
+#endif
+ if (lastpop <= 0) {
+ tc_BUMP();
+ }
+ level -= 1;
lastpop = -1;
break;
case 'l':
case 's':
- if (lastpop > 0)
+ if (lastpop > 0) {
+ level -= 1;
p_is_s[lastpop - 1] = dummy;
- ++number;
+ }
+ tc_BUMP();
break;
case 'p':
cp++;
i = (UChar(*cp) - '0');
if (i >= 0 && i <= NUM_PARM) {
+ ++level;
lastpop = i;
if (lastpop > *popcount)
*popcount = lastpop;
@@ -395,20 +408,22 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
break;
case 'P':
- ++number;
++cp;
break;
case 'g':
+ ++level;
cp++;
break;
case S_QUOTE:
+ ++level;
cp += 2;
lastpop = -1;
break;
case L_BRACE:
+ ++level;
cp++;
while (isdigit(UChar(*cp))) {
cp++;
@@ -428,14 +443,15 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
case '=':
case '<':
case '>':
+ tc_BUMP();
+ level -= 1; /* pop 2, operate, push 1 */
lastpop = -1;
- number += 2;
break;
case '!':
case '~':
+ tc_BUMP();
lastpop = -1;
- ++number;
break;
case 'i':
@@ -466,9 +482,13 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
int i;
const char *cp = string;
size_t len2;
+ bool termcap_hack;
+ bool incremented_two;
- if (cp == NULL)
+ if (cp == NULL) {
+ TR(TRACE_CALLS, ("%s: format is null", TPS(tname)));
return NULL;
+ }
TPS(out_used) = 0;
len2 = strlen(cp);
@@ -479,8 +499,12 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
* variable-length argument list.
*/
number = _nc_tparm_analyze(cp, p_is_s, &popcount);
- if (TPS(fmt_buff) == 0)
+ if (TPS(fmt_buff) == 0) {
+ TR(TRACE_CALLS, ("%s: error in analysis", TPS(tname)));
return NULL;
+ }
+
+ incremented_two = FALSE;
if (number > NUM_PARM)
number = NUM_PARM;
@@ -514,8 +538,9 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
* style, which means tparam() will expand termcap strings OK.
*/
TPS(stack_ptr) = 0;
+ termcap_hack = FALSE;
if (popcount == 0) {
- popcount = number;
+ termcap_hack = TRUE;
for (i = number - 1; i >= 0; i--) {
if (p_is_s[i])
spush(p_is_s[i]);
@@ -526,10 +551,16 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
#ifdef TRACE
if (USE_TRACEF(TRACE_CALLS)) {
for (i = 0; i < num_args; i++) {
- if (p_is_s[i] != 0)
+ if (p_is_s[i] != 0) {
save_text(", %s", _nc_visbuf(p_is_s[i]), 0);
- else
+ } else if ((long) param[i] > MAX_OF_TYPE(NCURSES_INT2) ||
+ (long) param[i] < 0) {
+ _tracef("BUG: problem with tparm parameter #%d of %d",
+ i + 1, num_args);
+ break;
+ } else {
save_number(", %d", (int) param[i], 0);
+ }
}
_tracef(T_CALLED("%s(%s%s)"), TPS(tname), _nc_visbuf(cp), TPS(out_buff));
TPS(out_used) = 0;
@@ -561,6 +592,20 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
save_char(npop());
break;
+#ifdef EXP_XTERM_1005
+ case 'u':
+ {
+ unsigned char target[10];
+ unsigned source = (unsigned) npop();
+ int rc = _nc_conv_to_utf8(target, source, (unsigned)
+ sizeof(target));
+ int n;
+ for (n = 0; n < rc; ++n) {
+ save_char(target[n]);
+ }
+ }
+ break;
+#endif
case 'l':
npush((int) strlen(spop()));
break;
@@ -573,10 +618,11 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
cp++;
i = (UChar(*cp) - '1');
if (i >= 0 && i < NUM_PARM) {
- if (p_is_s[i])
+ if (p_is_s[i]) {
spush(p_is_s[i]);
- else
+ } else {
npush((int) param[i]);
+ }
}
break;
@@ -645,11 +691,15 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
break;
case 'A':
- npush(npop() && npop());
+ y = npop();
+ x = npop();
+ npush(y && x);
break;
case 'O':
- npush(npop() || npop());
+ y = npop();
+ x = npop();
+ npush(y || x);
break;
case '&':
@@ -691,10 +741,26 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
break;
case 'i':
- if (p_is_s[0] == 0)
- param[0]++;
- if (p_is_s[1] == 0)
- param[1]++;
+ /*
+ * Increment the first two parameters -- if they are numbers
+ * rather than strings. As a side effect, assign into the
+ * stack; if this is termcap, then the stack was populated
+ * using the termcap hack above rather than via the terminfo
+ * 'p' case.
+ */
+ if (!incremented_two) {
+ incremented_two = TRUE;
+ if (p_is_s[0] == 0) {
+ param[0]++;
+ if (termcap_hack)
+ TPS(stack)[0].data.num = (int) param[0];
+ }
+ if (p_is_s[1] == 0) {
+ param[1]++;
+ if (termcap_hack)
+ TPS(stack)[1].data.num = (int) param[1];
+ }
+ }
break;
case '?':
@@ -774,7 +840,7 @@ tparam_internal(int use_TPARM_ARG, const char *string, va_list ap)
#endif
NCURSES_EXPORT(char *)
-tparm_varargs(NCURSES_CONST char *string,...)
+tparm_varargs(const char *string, ...)
{
va_list ap;
char *result;
@@ -791,7 +857,7 @@ tparm_varargs(NCURSES_CONST char *string,...)
#if !NCURSES_TPARM_VARARGS
NCURSES_EXPORT(char *)
-tparm_proto(NCURSES_CONST char *string,
+tparm_proto(const char *string,
TPARM_ARG a1,
TPARM_ARG a2,
TPARM_ARG a3,
@@ -807,7 +873,7 @@ tparm_proto(NCURSES_CONST char *string,
#endif /* NCURSES_TPARM_VARARGS */
NCURSES_EXPORT(char *)
-tiparm(const char *string,...)
+tiparm(const char *string, ...)
{
va_list ap;
char *result;