}
case STNUM: /* a numeric constant */
{ /* it may only be an integer constant */
- register int base = 10, val = 0, vch;
+ register int base = 10, vch;
+ register arith val = 0;
+ int ovfl = 0;
+ arith ubound = ~(1<<(sizeof(arith)*8-1))/(base/2);
/* Since the preprocessor only knows integers and has
* nothing to do with ellipsis we just return when the
}
while ((vch = val_in_base(ch, base)) >= 0) {
- val = val * base + vch; /* overflow? nah */
+ if (val < 0 || val > ubound) ovfl++;
+ val *= base;
+ if (val < 0 && val + vch >= 0) ovfl++;
+ val += vch;
ch = GetChar();
}
- while (ch == 'l' || ch == 'L' || ch == 'u' || ch == 'U')
+ ptok->tk_unsigned = 0;
+ if (ch == 'u' || ch == 'U') {
+ ptok->tk_unsigned = 1;
ch = GetChar();
+ if (ch == 'l' || ch == 'L') {
+ ch = GetChar();
+ }
+ }
+ else if (ch == 'l' || ch == 'L') {
+ ch = GetChar();
+ if (ch == 'u' || ch == 'U') {
+ ptok->tk_unsigned = 1;
+ ch = GetChar();
+ }
+ }
+ if (ovfl) {
+ warning("overflow in constant");
+ ptok->tk_unsigned = 1;
+ }
+ else if (val < 0) {
+ /* give warning??? */
+ ptok->tk_unsigned = 1;
+ }
UnGetChar();
ptok->tk_val = val;
return ptok->tk_symb = INTEGER;
int tok_symb; /* the token itself */
union {
char *tok_str;
- arith tok_val; /* for INTEGER */
+ struct {
+ int tok_unsigned;
+ arith tok_val; /* for INTEGER */
+ } tok_int;
} tok_data;
};
#define tk_symb tok_symb
#define tk_str tok_data.tok_str
-#define tk_val tok_data.tok_val
+#define tk_val tok_data.tok_int.tok_val
+#define tk_unsigned tok_data.tok_int.tok_unsigned
extern struct token dot;
#include "Lpars.h"
#include "arith.h"
-ch3bin(pval, oper, val)
+#define arith_sign (1 << (sizeof(arith)*8-1))
+
+ch3bin(pval, pis_uns, oper, val, is_uns)
register arith *pval, val;
- int oper;
+ int oper, is_uns, *pis_uns;
{
+ if (is_uns) *pis_uns = 1;
switch (oper) {
- case '%':
- if (val == 0)
- error("%% by 0");
- else
- *pval = *pval % val;
- break;
case '/':
- if (val == 0)
+ if (val == 0) {
error("/ by 0");
- else
+ break;
+ }
+ if (*pis_uns) {
+#ifdef UNSIGNED_ARITH
+ *pval /= (UNSIGNED_ARITH) val;
+#else
+ /* this is more of a problem than you might
+ think on C compilers which do not have
+ unsigned arith (== long (probably)).
+ */
+ if (val & arith_sign) {/* val > max_arith */
+ *pval = ! (*pval >= 0 || *pval < val);
+ /* this is the unsigned test
+ *pval < val for val > max_arith
+ */
+ }
+ else { /* val <= max_arith */
+ arith half, bit, hdiv, hrem, rem;
+
+ half = (*pval >> 1) & ~arith_sign;
+ bit = *pval & 01;
+ /* now *pval == 2 * half + bit
+ and half <= max_arith
+ and bit <= max_arith
+ */
+ hdiv = half / val;
+ hrem = half % val;
+ rem = 2 * hrem + bit;
+ *pval = 2 * hdiv + (rem < 0 || rem >= val);
+ /* that is the unsigned compare
+ rem >= val for val <= max_arith
+ */
+ }
+#endif
+ }
+ else {
+ *pval = *pval % val;
+ }
+ break;
+ case '%':
+ if (val == 0) {
+ error("%% by 0");
+ break;
+ }
+ if (*pis_uns) {
+#ifdef UNSIGNED_ARITH
+ *pval %= (UNSIGNED_ARITH) val;
+#else
+ if (val & arith_sign) {/* val > max_arith */
+ *pval = (*pval >= 0 || *pval < val) ? *pval : *pval - val;
+ /* this is the unsigned test
+ *pval < val for val > max_arith
+ */
+ }
+ else { /* val <= max_arith */
+ arith half, bit, hrem, rem;
+
+ half = (*pval >> 1) & ~arith_sign;
+ bit = *pval & 01;
+ /* now *pval == 2 * half + bit
+ and half <= max_arith
+ and bit <= max_arith
+ */
+ hrem = half % val;
+ rem = 2 * hrem + bit;
+ *pval = (rem < 0 || rem >= val) ? rem - val : rem;
+ }
+#endif
+ }
+ else {
*pval = *pval / val;
+ }
break;
case '*':
*pval = *pval * val;
*pval = *pval << val;
break;
case RIGHT:
- *pval = *pval >> val;
+ if (val == 0) break;
+ if (*pis_uns) {
+ *pval = (*pval >> 1) & ~arith_sign;
+ *pval = *pval >> (val - 1);
+ }
+ else *pval = *pval >> val;
break;
case '<':
- *pval = (*pval < val);
- break;
+ { arith tmp = *pval; *pval = val; val = tmp; }
+ /* fall through */
case '>':
- *pval = (*pval > val);
+ if (*pis_uns) {
+#ifdef UNSIGNED_ARITH
+ *pval = (UNSIGNED_ARITH) *pval > (UNSIGNED_ARITH) val;
+#else
+ *pval = (*pval & arith_sign ?
+ (val & arith_sign ? *pval > val : 1) :
+ (val & arith_sign ? 0 : *pval > val)
+ );
+#endif
+ }
+ else *pval = (*pval > val);
break;
case LESSEQ:
- *pval = (*pval <= val);
- break;
+ { arith tmp = *pval; *pval = val; val = tmp; }
+ /* fall through */
case GREATEREQ:
- *pval = (*pval >= val);
+ if (*pis_uns) {
+#ifdef UNSIGNED_ARITH
+ *pval = (UNSIGNED_ARITH) *pval >= (UNSIGNED_ARITH) val;
+#else
+ *pval = (*pval & arith_sign ?
+ (val & arith_sign ? *pval >= val : 1) :
+ (val & arith_sign ? 0 : *pval >= val)
+ );
+#endif
+ }
+ else *pval = (*pval >= val);
break;
case EQUAL:
*pval = (*pval == val);
*pval = (*pval || val);
break;
case ',':
+ *pis_uns = is_uns;
*pval = val;
break;
}
#include "Lpars.h"
#include "arith.h"
-ch3mon(oper, pval)
+/*ARGSUSED2*/
+ch3mon(oper, pval, puns)
register arith *pval;
+ int *puns;
{
switch (oper) {
case '~':
c = GetChar();
- repl->r_ptr = repl->r_text = Malloc(repl->r_size = ITEXTSIZE);
+ repl->r_ptr = repl->r_text = Malloc((unsigned)(repl->r_size = ITEXTSIZE));
*repl->r_ptr = '\0';
while ((c != EOI) && (class(c) != STNL)) {
if (BLANK(c)) {
char *s;
{
if (FileName) {
- fprint(ERROUT, "\"%s\", line %d: %s", FileName, LineNumber, s);
+ fprint(ERROUT, "\"%s\", line %d: %s", FileName, (int)LineNumber, s);
}
else fprint(ERROUT, s);
}
-/*VARARGS1*/
+/*VARARGS*/
error(va_alist)
va_dcl
{
va_end(ap);
}
-/*VARARGS1*/
+/*VARARGS*/
warning(va_alist)
va_dcl
{
va_end(ap);
}
-/*VARARGS1*/
+/*VARARGS*/
strict(va_alist)
va_dcl
{
va_end(ap);
}
-/*VARARGS1*/
+/*VARARGS*/
crash(va_alist)
va_dcl
{
sys_stop(S_ABORT);
}
-/*VARARGS1*/
+/*VARARGS*/
fatal(va_alist)
va_dcl
{
}
if_expression
+{ int is_unsigned = 0; }
:
- constant_expression(&ifval)
+ constant_expression(&ifval, &is_unsigned)
;
/* 7.1 */
-primary(arith *pval;)
+primary(arith *pval; int *is_uns;)
:
- constant(pval)
+ constant(pval, is_uns)
|
- '(' expression(pval) ')'
+ '(' expression(pval, is_uns) ')'
;
-unary(arith *pval;)
+unary(arith *pval; int *is_uns;)
{int oper;}
:
unop(&oper)
- unary(pval)
- { ch3mon(oper, pval); }
+ unary(pval, is_uns)
+ { ch3mon(oper, pval, is_uns); }
|
- primary(pval)
+ primary(pval, is_uns)
;
-binary_expression(int maxrank; arith *pval;)
- {int oper; arith val1;}
+binary_expression(int maxrank; arith *pval; int *is_uns;)
+ {int oper; arith val1; int u;}
:
- unary(pval)
+ unary(pval, is_uns)
[%while (rank_of(DOT) <= maxrank)
binop(&oper)
- binary_expression(rank_of(oper)-1, &val1)
+ binary_expression(rank_of(oper)-1, &val1, &u)
{
- ch3bin(pval, oper, val1);
+ ch3bin(pval, is_uns, oper, val1, u);
}
]*
;
/* 7.13 */
-conditional_expression(arith *pval;)
- {arith val1 = 0, val2 = 0;}
+conditional_expression(arith *pval; int *is_uns)
+ {arith val1 = 0, val2 = 0; int u;}
:
/* allow all binary operators */
- binary_expression(rank_of('?') - 1, pval)
+ binary_expression(rank_of('?') - 1, pval, is_uns)
[ '?'
- expression(&val1)
+ expression(&val1, is_uns)
':'
- assignment_expression(&val2)
- { *pval = (*pval ? val1 : val2); }
+ assignment_expression(&val2, &u)
+ { if (*pval) *pval = val1;
+ else { *pval = val2; *is_uns = u; }
+ }
]?
;
/* 7.14 */
-assignment_expression(arith *pval;)
+assignment_expression(arith *pval; int *is_uns)
:
- conditional_expression(pval)
+ conditional_expression(pval, is_uns)
;
/* 7.15 */
-expression(arith *pval;)
- {arith val1;}
+expression(arith *pval; int *is_uns)
+ {arith val1;
+ int is_uns1;
+ }
:
- assignment_expression(pval)
+ assignment_expression(pval,is_uns)
[ ','
- assignment_expression(&val1)
+ assignment_expression(&val1, &is_uns1)
{
- ch3bin(pval, ',', val1);
+ ch3bin(pval, is_uns, ',', val1, is_uns1);
}
]*
;
{*oper = DOT;}
;
-constant(arith *pval;) :
+constant(arith *pval; int *is_uns) :
INTEGER
- {*pval = dot.tk_val;}
+ {*pval = dot.tk_val;
+ *is_uns = dot.tk_unsigned;
+ }
;
-constant_expression (arith *pval;) :
- assignment_expression(pval)
+constant_expression (arith *pval; int *is_uns) :
+ assignment_expression(pval, is_uns)
;
};
char *strcpy();
+char *sprint();
init_pp()
{
#define INP_VAR finfo
struct file_info finfo;
#include <inp_pkg.body>
+#include <alloc.h>
char *
getwdir(fn)
#endif
extern int InputLevel;
+extern char *sprint();
+
Xflush()
{
sys_write(STDOUT, _obuf, OBUFSIZE);
do_pragma()
{
register int size = ITEXTSIZE;
- char *cur_line = Malloc(size);
+ char *cur_line = Malloc((unsigned)size);
register char *c_ptr = cur_line;
register int c = GetChar();
register int delim = 0;
register char *p = Xbuf; \
sprint(Xbuf, "%s %d \"%s\"\n", \
LINE_PREFIX, \
- LineNumber, \
+ (int)LineNumber, \
FileName); \
op--; \
while (op >= _obuf \
if (idf->id_macro->mc_flag & NOREPLACE)
return 0;
repl = new_repl();
- repl->r_ptr = repl->r_text = Malloc(repl->r_size = LAPBUF);
+ repl->r_ptr = repl->r_text = Malloc((unsigned)(repl->r_size = LAPBUF));
repl->r_args = new_args();
repl->r_idf = idf;
if (!expand_macro(repl, idf))
newarg(args)
struct args *args;
{
- args->a_expptr = args->a_expbuf = Malloc(args->a_expsize = ARGBUF);
- args->a_rawptr = args->a_rawbuf = Malloc(args->a_rawsize = ARGBUF);
+ args->a_expptr = args->a_expbuf = Malloc((unsigned)(args->a_expsize = ARGBUF));
+ args->a_rawptr = args->a_rawbuf = Malloc((unsigned)(args->a_rawsize = ARGBUF));
}
getactuals(repl, idf)
register int ch = 0;
register int level = 0, nostashraw = 0;
int lastch;
+ static int Unstacked_missed;
while (1) {
lastch = ch;
ch = GetChar();
+ if (nostashraw
+ && nostashraw >= Unstacked_missed) {
+ nostashraw -= Unstacked_missed;
+ Unstacked_missed = 0;
+ }
if (Unstacked) {
nostashraw -= Unstacked;
- if (nostashraw < 0) nostashraw = 0;
+ if (nostashraw < 0) {
+ Unstacked_missed = -nostashraw;
+ nostashraw = 0;
+ }
EnableMacros();
}
if (class(ch) == STIDF || class(ch) == STELL) {