|
473 | 473 | return src;
|
474 | 474 | }
|
475 | 475 |
|
| 476 | +/*********************************************************************** |
| 477 | +** |
| 478 | +*/ const REBYTE *Scan_Quote_Binary(const REBYTE *src, SCAN_STATE *scan_state) |
| 479 | +/* |
| 480 | +** Scan a binary string, remove spaceces and comments. |
| 481 | +** |
| 482 | +** The result will be put into the temporary MOLD_BUF binary. |
| 483 | +** |
| 484 | +***********************************************************************/ |
| 485 | +{ |
| 486 | + REBOOL comm = FALSE; |
| 487 | + REBINT chr; |
| 488 | + REBCNT lines = 0; |
| 489 | + REBSER *buf = BUF_MOLD; |
| 490 | + |
| 491 | + RESET_TAIL(buf); |
| 492 | + |
| 493 | + if (*src++ != '{') return 0; |
| 494 | + |
| 495 | + while (*src != '}') { |
| 496 | + chr = *src; |
| 497 | + |
| 498 | + switch (chr) { |
| 499 | + |
| 500 | + case 0: |
| 501 | + return 0; // Scan_state shows error location. |
| 502 | + case '^': |
| 503 | + chr = Scan_Char(&src); |
| 504 | + if (chr == -1) return 0; |
| 505 | + src--; |
| 506 | + break; |
| 507 | + case ';': |
| 508 | + while (chr != 0) { |
| 509 | + chr = *++src; |
| 510 | + if (chr == '^') { |
| 511 | + chr = Scan_Char(&src); |
| 512 | + if (chr == -1) return 0; |
| 513 | + src--; |
| 514 | + } |
| 515 | + if (chr == LF || chr == CR) { |
| 516 | + goto new_line; |
| 517 | + } |
| 518 | + } |
| 519 | + return 0; // end of input reached |
| 520 | + case CR: |
| 521 | + if (src[1] == LF) src++; |
| 522 | + // fall thru |
| 523 | + case LF: |
| 524 | +new_line: |
| 525 | + lines++; |
| 526 | + // fall thru |
| 527 | + case ' ': |
| 528 | + case TAB: |
| 529 | + src++; |
| 530 | + continue; |
| 531 | + |
| 532 | + default: |
| 533 | + if (chr >= 0x80) return 0; |
| 534 | + } |
| 535 | + |
| 536 | + src++; |
| 537 | + |
| 538 | + if (SERIES_FULL(buf)) |
| 539 | + Extend_Series(buf, 1); |
| 540 | + |
| 541 | + *BIN_SKIP(buf, buf->tail) = chr; |
| 542 | + buf->tail++; |
| 543 | + } |
| 544 | + |
| 545 | + src++; // Skip ending quote or brace. |
| 546 | + |
| 547 | + if (scan_state) scan_state->line_count += lines; |
| 548 | + |
| 549 | + STR_TERM(buf); |
| 550 | + |
| 551 | + return src; |
| 552 | +} |
| 553 | + |
476 | 554 |
|
477 | 555 | /***********************************************************************
|
478 | 556 | **
|
|
929 | 1007 | if (*cp == '{') { /* BINARY #{12343132023902902302938290382} */
|
930 | 1008 | scan_state->end = scan_state->begin; /* save start */
|
931 | 1009 | scan_state->begin = cp;
|
932 |
| - cp = Scan_Quote(cp, scan_state); // stores result string in BUF_MOLD !!?? |
| 1010 | + // Originally there was used Scan_Quote collecting into BUF_MOLD, but this was not used later. |
| 1011 | + // It was wasting resources, because Scan_Quote collects unicode (2 bytes per char). |
| 1012 | + // Scan_Quote_Binary collects ANSI and report invalit input (like unicode char) much sooner. |
| 1013 | + // It also skips spaces and line-comments so these should not have to be tested by Decode_Binary later. |
| 1014 | + cp = Scan_Quote_Binary(cp, scan_state); // stores result string in BUF_MOLD !!?? |
933 | 1015 | scan_state->begin = scan_state->end; /* restore start */
|
934 | 1016 | if (cp) {
|
935 | 1017 | scan_state->end = cp;
|
@@ -1436,7 +1518,9 @@ extern REBSER *Scan_Full_Block(SCAN_STATE *scan_state, REBYTE mode_char);
|
1436 | 1518 | break;
|
1437 | 1519 |
|
1438 | 1520 | case TOKEN_BINARY:
|
1439 |
| - Scan_Binary(bp, len, value); |
| 1521 | + // In BUF_MOLD is preprocessed ANSI result without comments and spaces |
| 1522 | + // we just still need to resolve the binary base (like `64#{`) from the input |
| 1523 | + Scan_Binary(Scan_Binary_Base(bp, len), BIN_DATA(BUF_MOLD), BIN_LEN(BUF_MOLD), value); |
1440 | 1524 | LABEL_SERIES(VAL_SERIES(value), "scan binary");
|
1441 | 1525 | break;
|
1442 | 1526 |
|
|
0 commit comments