FreeBSD/contrib/mdocml/roff.c
/*
 * Evaluate a complete numeric expression.
 * Proceed left to right, there is no concept of precedence.
 */
Evaluate a complete numeric expression.
Proceed left to right, there is no concept of precedence.
Evaluate a complete numeric expression . Proceed left to right there is no concept of precedence .
static int
roff_evalnum(struct roff *r, int ln, const char *v,
	int *pos, int *res, int flags)
{
	int		 mypos, operand2;
	char		 operator;
	if (NULL == pos) {
		mypos = 0;
		pos = &mypos;
	}
	if (flags & ROFFNUM_WHITE)
		while (isspace((unsigned char)v[*pos]))
			(*pos)++;
	if ( ! roff_evalpar(r, ln, v, pos, res, flags))
		return 0;
	while (1) {
		if (flags & ROFFNUM_WHITE)
			while (isspace((unsigned char)v[*pos]))
				(*pos)++;
		if ( ! roff_getop(v, pos, &operator))
			break;
		if (flags & ROFFNUM_WHITE)
			while (isspace((unsigned char)v[*pos]))
				(*pos)++;
		if ( ! roff_evalpar(r, ln, v, pos, &operand2, flags))
			return 0;
		if (flags & ROFFNUM_WHITE)
			while (isspace((unsigned char)v[*pos]))
				(*pos)++;
		if (NULL == res)
			continue;
		switch (operator) {
		case '+':
			*res += operand2;
			break;
		case '-':
			*res -= operand2;
			break;
		case '*':
			*res *= operand2;
			break;
		case '/':
			if (operand2 == 0) {
				mandoc_msg(MANDOCERR_DIVZERO,
					r->parse, ln, *pos, v);
				*res = 0;
				break;
			}
			*res /= operand2;
			break;
		case '%':
			if (operand2 == 0) {
				mandoc_msg(MANDOCERR_DIVZERO,
					r->parse, ln, *pos, v);
				*res = 0;
				break;
			}
			*res %= operand2;
			break;
		case '<':
			*res = *res < operand2;
			break;
		case '>':
			*res = *res > operand2;
			break;
		case 'l':
			*res = *res <= operand2;
			break;
		case 'g':
			*res = *res >= operand2;
			break;
		case '=':
			*res = *res == operand2;
			break;
		case '!':
			*res = *res != operand2;
			break;
		case '&':
			*res = *res && operand2;
			break;
		case ':':
			*res = *res || operand2;
			break;
		case 'i':
			if (operand2 < *res)
				*res = operand2;
			break;
		case 'a':
			if (operand2 > *res)
				*res = operand2;
			break;
		default:
			abort();
		}
	}
	return 1;
}
static int roff_evalnum ( struct roff * r , int ln , const char * v , int * pos , int * res , int flags ) { int mypos , operand2 ; char operator ; if ( NULL == pos ) { mypos = 0 ; pos = & mypos ; } if ( flags & ROFFNUM_WHITE ) while ( isspace ( ( unsigned char ) v [ * pos ] ) ) ( * pos ) ++ ; if ( ! roff_evalpar ( r , ln , v , pos , res , flags ) ) return 0 ; while ( 1 ) { if ( flags & ROFFNUM_WHITE ) while ( isspace ( ( unsigned char ) v [ * pos ] ) ) ( * pos ) ++ ; if ( ! roff_getop ( v , pos , & operator ) ) break ; if ( flags & ROFFNUM_WHITE ) while ( isspace ( ( unsigned char ) v [ * pos ] ) ) ( * pos ) ++ ; if ( ! roff_evalpar ( r , ln , v , pos , & operand2 , flags ) ) return 0 ; if ( flags & ROFFNUM_WHITE ) while ( isspace ( ( unsigned char ) v [ * pos ] ) ) ( * pos ) ++ ; if ( NULL == res ) continue ; switch ( operator ) { case ' ' : * res += operand2 ; break ; case ' ' : * res -= operand2 ; break ; case ' ' : * res *= operand2 ; break ; case ' ' : if ( operand2 == 0 ) { mandoc_msg ( MANDOCERR_DIVZERO , r -> parse , ln , * pos , v ) ; * res = 0 ; break ; } * res /= operand2 ; break ; case ' ' : if ( operand2 == 0 ) { mandoc_msg ( MANDOCERR_DIVZERO , r -> parse , ln , * pos , v ) ; * res = 0 ; break ; } * res %= operand2 ; break ; case ' ' : * res = * res < operand2 ; break ; case ' ' : * res = * res > operand2 ; break ; case ' ' : * res = * res <= operand2 ; break ; case ' ' : * res = * res >= operand2 ; break ; case ' ' : * res = * res == operand2 ; break ; case ' ' : * res = * res != operand2 ; break ; case ' ' : * res = * res && operand2 ; break ; case ' ' : * res = * res || operand2 ; break ; case ' ' : if ( operand2 < * res ) * res = operand2 ; break ; case ' ' : if ( operand2 > * res ) * res = operand2 ; break ; default : abort ( ) ; } } return 1 ; }
Evaluate a complete numeric expression.
Evaluate a complete numeric expression .