lib_tpar.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 770 行 · 第 1/2 页
C
770 行
*
* 'number' counts coarsely the number of pop's we see in the string, and
* 'popcount' shows the highest parameter number in the string. We would
* like to simply use the latter count, but if we are reading termcap
* strings, there may be cases that we cannot see the explicit parameter
* numbers.
*/
for (cp = string; (cp - string) < (int) len2;) {
if (*cp == '%') {
cp++;
cp = parse_format(cp, format, &len);
switch (*cp) {
default:
break;
case 'd': /* FALLTHRU */
case 'o': /* FALLTHRU */
case 'x': /* FALLTHRU */
case 'X': /* FALLTHRU */
case 'c': /* FALLTHRU */
number++;
lastpop = -1;
break;
case 'l':
case 's':
if (lastpop > 0)
p_is_s[lastpop - 1] = dummy;
++number;
break;
case 'p':
cp++;
i = (*cp - '0');
if (i >= 0 && i <= 9) {
lastpop = i;
if (lastpop > popcount)
popcount = lastpop;
}
break;
case 'P':
++number;
++cp;
break;
case 'g':
cp++;
break;
case S_QUOTE:
cp += 2;
lastpop = -1;
break;
case L_BRACE:
cp++;
while (*cp >= '0' && *cp <= '9') {
cp++;
}
break;
case '+':
case '-':
case '*':
case '/':
case 'm':
case 'A':
case 'O':
case '&':
case '|':
case '^':
case '=':
case '<':
case '>':
lastpop = -1;
number += 2;
break;
case '!':
case '~':
lastpop = -1;
++number;
break;
case 'i':
lastpop = -1;
if (popcount < 2)
popcount = 2;
break;
}
}
if (*cp != '\0')
cp++;
}
if (number > 9)
number = 9;
for (i = 0; i < max(popcount, number); i++) {
/*
* A few caps (such as plab_norm) have string-valued parms.
* We'll have to assume that the caller knows the difference, since
* a char* and an int may not be the same size on the stack. The
* normal prototype for this uses 9 long's, which is consistent with
* our va_arg() usage.
*/
if (p_is_s[i] != 0) {
p_is_s[i] = va_arg(ap, char *);
} else {
param[i] = va_arg(ap, long int);
}
}
/*
* This is a termcap compatibility hack. If there are no explicit pop
* operations in the string, load the stack in such a way that
* successive pops will grab successive parameters. That will make
* the expansion of (for example) \E[%d;%dH work correctly in termcap
* style, which means tparam() will expand termcap strings OK.
*/
stack_ptr = 0;
if (popcount == 0) {
popcount = number;
for (i = number - 1; i >= 0; i--)
npush(param[i]);
}
#ifdef TRACE
if (_nc_tracing & TRACE_CALLS) {
for (i = 0; i < popcount; i++) {
if (p_is_s[i] != 0)
save_text(", %s", _nc_visbuf(p_is_s[i]), 0);
else
save_number(", %d", param[i], 0);
}
_tracef(T_CALLED("%s(%s%s)"), tname, _nc_visbuf(string), out_buff);
out_used = 0;
}
#endif /* TRACE */
while (*string) {
if (*string != '%') {
save_char(*string);
} else {
tparam_base = string++;
string = parse_format(string, format, &len);
switch (*string) {
default:
break;
case '%':
save_char('%');
break;
case 'd': /* FALLTHRU */
case 'o': /* FALLTHRU */
case 'x': /* FALLTHRU */
case 'X': /* FALLTHRU */
save_number(format, npop(), len);
break;
case 'c': /* FALLTHRU */
save_char(npop());
break;
case 'l':
save_number("%d", (int) strlen(spop()), 0);
break;
case 's':
save_text(format, spop(), len);
break;
case 'p':
string++;
i = (*string - '1');
if (i >= 0 && i < 9) {
if (p_is_s[i])
spush(p_is_s[i]);
else
npush(param[i]);
}
break;
case 'P':
string++;
if (isUPPER(*string)) {
i = (*string - 'A');
static_vars[i] = npop();
} else if (isLOWER(*string)) {
i = (*string - 'a');
dynamic_var[i] = npop();
}
break;
case 'g':
string++;
if (isUPPER(*string)) {
i = (*string - 'A');
npush(static_vars[i]);
} else if (isLOWER(*string)) {
i = (*string - 'a');
npush(dynamic_var[i]);
}
break;
case S_QUOTE:
string++;
npush(*string);
string++;
break;
case L_BRACE:
number = 0;
string++;
while (*string >= '0' && *string <= '9') {
number = number * 10 + *string - '0';
string++;
}
npush(number);
break;
case '+':
npush(npop() + npop());
break;
case '-':
y = npop();
x = npop();
npush(x - y);
break;
case '*':
npush(npop() * npop());
break;
case '/':
y = npop();
x = npop();
npush(y ? (x / y) : 0);
break;
case 'm':
y = npop();
x = npop();
npush(y ? (x % y) : 0);
break;
case 'A':
npush(npop() && npop());
break;
case 'O':
npush(npop() || npop());
break;
case '&':
npush(npop() & npop());
break;
case '|':
npush(npop() | npop());
break;
case '^':
npush(npop() ^ npop());
break;
case '=':
y = npop();
x = npop();
npush(x == y);
break;
case '<':
y = npop();
x = npop();
npush(x < y);
break;
case '>':
y = npop();
x = npop();
npush(x > y);
break;
case '!':
npush(!npop());
break;
case '~':
npush(~npop());
break;
case 'i':
if (p_is_s[0] == 0)
param[0]++;
if (p_is_s[1] == 0)
param[1]++;
break;
case '?':
break;
case 't':
x = npop();
if (!x) {
/* scan forward for %e or %; at level zero */
string++;
level = 0;
while (*string) {
if (*string == '%') {
string++;
if (*string == '?')
level++;
else if (*string == ';') {
if (level > 0)
level--;
else
break;
} else if (*string == 'e' && level == 0)
break;
}
if (*string)
string++;
}
}
break;
case 'e':
/* scan forward for a %; at level zero */
string++;
level = 0;
while (*string) {
if (*string == '%') {
string++;
if (*string == '?')
level++;
else if (*string == ';') {
if (level > 0)
level--;
else
break;
}
}
if (*string)
string++;
}
break;
case ';':
break;
} /* endswitch (*string) */
} /* endelse (*string == '%') */
if (*string == '\0')
break;
string++;
} /* endwhile (*string) */
get_space(1);
out_buff[out_used] = '\0';
T((T_RETURN("%s"), _nc_visbuf(out_buff)));
return (out_buff);
}
NCURSES_EXPORT(char *)
tparm(NCURSES_CONST char *string,...)
{
va_list ap;
char *result;
_nc_tparm_err = 0;
va_start(ap, string);
#ifdef TRACE
tname = "tparm";
#endif /* TRACE */
result = tparam_internal(string, ap);
va_end(ap);
return result;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?