#ifdef M_RCSID
#ifndef lint
static char rcsID[] = "$Header: /rd/src/libc/xcurses/rcs/tparm.c 1.2 1995/08/31 19:44:03 danv Exp $";
#endif
#endif
#include <private.h>
#include <ctype.h>
#include <stdarg.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 : (char *) 0)
typedef union {
unsigned int num;
char* str;
} stack_frame;
static char buffer[256];
const char *
#ifdef STDARG_VERSION
tparm(const char *string, ...)
#else
tparm(string, p1, p2, p3, p4, p5, p6, p7, p8, p9)
const char *string;
long p1, p2, p3, p4, p5, p6, p7, p8, p9;
#endif
{
char len;
long parm[9];
va_list vparm;
int varyable[26];
int number, level, x, y;
int stack_ptr = 0;
stack_frame stack[STACKSIZE];
char *bufptr = buffer;
#ifdef STDARG_VERSION
va_start(vparm, string);
for (x = 0; x < 9; ++x)
parm[x] = va_arg(vparm, long);
va_end(vparm);
#else
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;
#endif
#ifdef M_CURSES_TRACE
__m_trace(
"tparm(\"%s\", %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld)",
string, parm[0],
parm[1], parm[2], parm[3], parm[4],
parm[5], parm[6], parm[7], parm[8]
);
#endif
while (*string) {
if (*string != '%')
*(bufptr++) = *string;
else {
string++;
switch (*string) {
default:
break;
case '%':
*(bufptr++) = '%';
break;
case 'd':
bufptr += sprintf(bufptr, "%ld", npop());
break;
case '0':
len = -(*++string - '0');
if ((len == (char)-2 || len == (char)-3)
&& *++string == 'd')
bufptr += sprintf(
bufptr, "%0*ld", len, npop()
);
break;
case '2':
case '3':
len = *string++ - '0';
if (*string == 'd')
bufptr += sprintf(
bufptr, "%*ld", len, npop()
);
break;
case 'c':
*(bufptr++) = (char) npop();
break;
case 's':
strcpy(bufptr, spop());
bufptr += strlen(bufptr);
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 '+':
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 '/':
y = npop();
x = npop();
npush(x / y);
break;
case 'm':
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 '^':
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 '>':
y = npop();
x = npop();
npush(x > y);
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 __m_return_pointer("tparm", buffer);
}