#ifdef M_RCSID
#ifndef lint
static char rcsID[] =
"$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/"
"libxcurses/src/libc/xcurses/rcs/tparm.c 1.3 1998/06/03 12:57:01 "
"cbates Exp $";
#endif
#endif
#include <private.h>
#include <ctype.h>
#include <string.h>
#include <m_ord.h>
#define STACKSIZE 20
#define npush(x) \
if (stack_ptr < STACKSIZE) {\
stack[stack_ptr].num = x; \
stack_ptr++; \
}
#define npop() (stack_ptr > 0 ? stack[--stack_ptr].num : 0)
#define spop() (stack_ptr > 0 ? stack[--stack_ptr].str : NULL)
typedef union {
unsigned long num;
char *str;
} stack_frame;
static char buffer[256];
char *
tparm(char *string,
long p1, long p2, long p3, long p4, long p5,
long p6, long p7, long p8, long p9)
{
size_t len;
long parm[9];
unsigned long number, x, y;
unsigned long varyable[26];
int level;
int stack_ptr = 0;
stack_frame stack[STACKSIZE];
char *bufptr = buffer;
char format[20];
parm[0] = p1;
parm[1] = p2;
parm[2] = p3;
parm[3] = p4;
parm[4] = p5;
parm[5] = p6;
parm[6] = p7;
parm[7] = p8;
parm[8] = p9;
(void) strcpy(format, "%");
while (*string) {
if (*string != '%')
*(bufptr++) = *string;
else {
string++;
switch (*string) {
case ':':
string++;
default:
while (*string) {
switch (*string) {
case 'd':
case 'o':
case 'x':
case 'X':
(void) strcat(format, "l");
len = strlen(format);
format[len] = *string;
format[len+1] = '\0';
bufptr += sprintf(bufptr,
format, npop());
(void) strcpy(format, "%");
goto break_out;
case 's':
(void) strcat(format, "s");
bufptr += sprintf(bufptr,
format, spop());
(void) strcpy(format, "%");
goto break_out;
case ' ':
case '.':
case '-':
case '+':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '#':
len = strlen(format);
format[len] = *string;
format[len+1] = '\0';
break;
}
string++;
}
break_out:
break;
case '%':
*(bufptr++) = '%';
break;
case 'c':
*(bufptr++) = (char) npop();
break;
case 'l':
len = strlen(spop());
npush(len);
break;
case 'p':
string++;
if ('1' <= *string && *string <= '9')
npush(parm[*string - '1']);
break;
case 'P':
{
int i;
int c;
++string;
c = (int)*string;
i = m_ord(c);
if (0 < i)
varyable[i-1] = npop();
break;
}
case 'g':
{
int i;
int c;
++string;
c = (int)*string;
i = m_ord(c);
if (0 < i)
npush(varyable[i-1]);
break;
}
case '\'':
string++;
npush(*string);
string++;
break;
case '{':
number = 0;
string++;
while ('0' <= *string && *string <= '9') {
number = number * 10 + *string - '0';
string++;
}
npush(number);
break;
case '+':
case '-':
case '*':
case '/':
case 'm':
case '&':
case '|':
case '^':
case '=':
case '<':
case '>':
case 'A':
case 'O':
y = npop();
x = npop();
switch (*string) {
case '+':
npush(x + y);
break;
case '-':
npush(x - y);
break;
case '*':
npush(x * y);
break;
case '/':
npush(x / y);
break;
case 'm':
npush(x % y);
break;
case '&':
npush(x & y);
break;
case '|':
npush(x | y);
break;
case '^':
npush(x ^ y);
break;
case '<':
npush(x < y);
break;
case '>':
npush(x > y);
break;
case '=':
npush(x == y);
break;
case 'A':
npush(x && y);
break;
case 'O':
npush(x || y);
break;
}
break;
case '!':
x = npop();
npush(!x);
break;
case '~':
x = npop();
npush(~x);
break;
case 'i':
parm[0]++;
parm[1]++;
break;
case '?':
break;
case 't':
x = npop();
if (x) {
} else {
string++;
level = 0;
while (*string) {
if (*string == '%') {
string++;
if (*string == '?')
level++;
else if (*string == ';') {
if (level <= 0)
break;
level--;
} else if (*string == 'e' && level == 0)
break;
}
if (*string)
string++;
}
}
break;
case 'e':
string++;
level = 0;
while (*string) {
if (*string == '%') {
string++;
if (*string == '?')
level++;
else if (*string == ';') {
if (level <= 0)
break;
level--;
}
}
if (*string)
string++;
}
break;
case ';':
break;
}
}
if (*string == '\0')
break;
string++;
}
*bufptr = '\0';
return (buffer);
}