Index: trunk/extensions/ParserFunctions/Expr.php |
— | — | @@ -103,6 +103,7 @@ |
104 | 104 | 'expr_unexpected_closing_bracket' => 'Expression error: unexpected closing bracket',
|
105 | 105 | 'expr_unrecognised_punctuation' => 'Expression error: unrecognised punctuation character "$1"',
|
106 | 106 | 'expr_unclosed_bracket' => 'Expression error: unclosed bracket',
|
| 107 | + 'expr_division_by_zero' => 'Division by zero',
|
107 | 108 | ));
|
108 | 109 | }
|
109 | 110 |
|
— | — | @@ -256,8 +257,8 @@ |
257 | 258 | } elseif ( $char == ')' ) {
|
258 | 259 | $lastOp = end( $operators );
|
259 | 260 | while ( $lastOp && $lastOp != EXPR_OPEN ) {
|
260 | | - if ( !$this->doOperation( $lastOp, $operands ) ) {
|
261 | | - $this->error( 'missing_operand', $this->names[$lastOp] );
|
| 261 | + if ( true !== ( $error = $this->doOperation( $lastOp, $operands ) ) ) {
|
| 262 | + $this->error( $error, $this->names[$lastOp] );
|
262 | 263 | return false;
|
263 | 264 | }
|
264 | 265 | array_pop( $operators );
|
— | — | @@ -298,8 +299,8 @@ |
299 | 300 | // Shunting yard magic
|
300 | 301 | $lastOp = end( $operators );
|
301 | 302 | while ( $lastOp && $this->precedence[$op] <= $this->precedence[$lastOp] ) {
|
302 | | - if ( !$this->doOperation( $lastOp, $operands ) ) {
|
303 | | - $this->error( 'missing_operand', $this->names[$lastOp] );
|
| 303 | + if ( true !== ( $error = $this->doOperation( $lastOp, $operands ) ) ) {
|
| 304 | + $this->error( $error, $this->names[$lastOp] );
|
304 | 305 | return false;
|
305 | 306 | }
|
306 | 307 | array_pop( $operators );
|
— | — | @@ -315,8 +316,8 @@ |
316 | 317 | $this->error( 'unclosed_bracket' );
|
317 | 318 | return false;
|
318 | 319 | }
|
319 | | - if ( !$this->doOperation( $op, $operands ) ) {
|
320 | | - $this->error( 'missing_operand', $this->names[$op] );
|
| 320 | + if ( true !== ( $error = $this->doOperation( $op, $operands ) ) ) {
|
| 321 | + $this->error( $error, $this->names[$op] );
|
321 | 322 | return false;
|
322 | 323 | }
|
323 | 324 | }
|
— | — | @@ -327,98 +328,100 @@ |
328 | 329 | function doOperation( $op, &$stack ) {
|
329 | 330 | switch ( $op ) {
|
330 | 331 | case EXPR_NEGATIVE:
|
331 | | - if ( count( $stack ) < 1 ) return false;
|
| 332 | + if ( count( $stack ) < 1 ) return 'missing_operand';
|
332 | 333 | $arg = array_pop( $stack );
|
333 | 334 | $stack[] = -$arg;
|
334 | 335 | break;
|
335 | 336 | case EXPR_POSITIVE:
|
336 | | - if ( count( $stack ) < 1 ) return false;
|
| 337 | + if ( count( $stack ) < 1 ) return 'missing_operand';
|
337 | 338 | break;
|
338 | 339 | case EXPR_TIMES:
|
339 | | - if ( count( $stack ) < 2 ) return false;
|
| 340 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
340 | 341 | $right = array_pop( $stack );
|
341 | 342 | $left = array_pop( $stack );
|
342 | 343 | $stack[] = $left * $right;
|
343 | 344 | break;
|
344 | 345 | case EXPR_DIVIDE:
|
345 | | - if ( count( $stack ) < 2 ) return false;
|
| 346 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
346 | 347 | $right = array_pop( $stack );
|
347 | 348 | $left = array_pop( $stack );
|
| 349 | + if ( $right == 0 ) return 'division_by_zero';
|
348 | 350 | $stack[] = $left / $right;
|
349 | 351 | break;
|
350 | 352 | case EXPR_MOD:
|
351 | | - if ( count( $stack ) < 2 ) return false;
|
| 353 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
352 | 354 | $right = array_pop( $stack );
|
353 | 355 | $left = array_pop( $stack );
|
| 356 | + if ( $right == 0 ) return 'division_by_zero';
|
354 | 357 | $stack[] = $left % $right;
|
355 | 358 | break;
|
356 | 359 | case EXPR_PLUS:
|
357 | | - if ( count( $stack ) < 2 ) return false;
|
| 360 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
358 | 361 | $right = array_pop( $stack );
|
359 | 362 | $left = array_pop( $stack );
|
360 | 363 | $stack[] = $left + $right;
|
361 | 364 | break;
|
362 | 365 | case EXPR_MINUS:
|
363 | | - if ( count( $stack ) < 2 ) return false;
|
| 366 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
364 | 367 | $right = array_pop( $stack );
|
365 | 368 | $left = array_pop( $stack );
|
366 | 369 | $stack[] = $left - $right;
|
367 | 370 | break;
|
368 | 371 | case EXPR_AND:
|
369 | | - if ( count( $stack ) < 2 ) return false;
|
| 372 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
370 | 373 | $right = array_pop( $stack );
|
371 | 374 | $left = array_pop( $stack );
|
372 | 375 | $stack[] = ( $left && $right ) ? 1 : 0;
|
373 | 376 | break;
|
374 | 377 | case EXPR_OR:
|
375 | | - if ( count( $stack ) < 2 ) return false;
|
| 378 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
376 | 379 | $right = array_pop( $stack );
|
377 | 380 | $left = array_pop( $stack );
|
378 | 381 | $stack[] = ( $left || $right ) ? 1 : 0;
|
379 | 382 | break;
|
380 | 383 | case EXPR_EQUALITY:
|
381 | | - if ( count( $stack ) < 2 ) return false;
|
| 384 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
382 | 385 | $right = array_pop( $stack );
|
383 | 386 | $left = array_pop( $stack );
|
384 | 387 | $stack[] = ( $left == $right ) ? 1 : 0;
|
385 | 388 | break;
|
386 | 389 | case EXPR_NOT:
|
387 | | - if ( count( $stack ) < 1 ) return false;
|
| 390 | + if ( count( $stack ) < 1 ) return 'missing_operand';
|
388 | 391 | $arg = array_pop( $stack );
|
389 | 392 | $stack[] = (!$arg) ? 1 : 0;
|
390 | 393 | break;
|
391 | 394 | case EXPR_ROUND:
|
392 | | - if ( count( $stack ) < 2 ) return false;
|
| 395 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
393 | 396 | $digits = intval( array_pop( $stack ) );
|
394 | 397 | $value = array_pop( $stack );
|
395 | 398 | $stack[] = round( $value, $digits );
|
396 | 399 | break;
|
397 | 400 | case EXPR_LESS:
|
398 | | - if ( count( $stack ) < 2 ) return false;
|
| 401 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
399 | 402 | $right = array_pop( $stack );
|
400 | 403 | $left = array_pop( $stack );
|
401 | 404 | $stack[] = ( $left < $right ) ? 1 : 0;
|
402 | 405 | break;
|
403 | 406 | case EXPR_GREATER:
|
404 | | - if ( count( $stack ) < 2 ) return false;
|
| 407 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
405 | 408 | $right = array_pop( $stack );
|
406 | 409 | $left = array_pop( $stack );
|
407 | 410 | $stack[] = ( $left > $right ) ? 1 : 0;
|
408 | 411 | break;
|
409 | 412 | case EXPR_LESSEQ:
|
410 | | - if ( count( $stack ) < 2 ) return false;
|
| 413 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
411 | 414 | $right = array_pop( $stack );
|
412 | 415 | $left = array_pop( $stack );
|
413 | 416 | $stack[] = ( $left <= $right ) ? 1 : 0;
|
414 | 417 | break;
|
415 | 418 | case EXPR_GREATEREQ:
|
416 | | - if ( count( $stack ) < 2 ) return false;
|
| 419 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
417 | 420 | $right = array_pop( $stack );
|
418 | 421 | $left = array_pop( $stack );
|
419 | 422 | $stack[] = ( $left >= $right ) ? 1 : 0;
|
420 | 423 | break;
|
421 | 424 | case EXPR_NOTEQ:
|
422 | | - if ( count( $stack ) < 2 ) return false;
|
| 425 | + if ( count( $stack ) < 2 ) return 'missing_operand';
|
423 | 426 | $right = array_pop( $stack );
|
424 | 427 | $left = array_pop( $stack );
|
425 | 428 | $stack[] = ( $left != $right ) ? 1 : 0;
|