------------------------------------------------------------------ */ to-number -- conversion from numeric string */ / decNumberFromString -- convert string to decNumber */ dn -- the number structure to fill */ chars[] -- the string to convert ('\0' terminated) */ set -- the context used for processing any err
| 476 | /* If bad syntax is detected, the result will be a quiet NaN. */ |
| 477 | /* ------------------------------------------------------------------ */ |
| 478 | decNumber * decNumberFromString(decNumber *dn, const char chars[], |
| 479 | decContext *set) { |
| 480 | Int exponent=0; // working exponent [assume 0] |
| 481 | uByte bits=0; // working flags [assume +ve] |
| 482 | Unit *res; // where result will be built |
| 483 | Unit resbuff[SD2U(DECBUFFER+9)];// local buffer in case need temporary |
| 484 | // [+9 allows for ln() constants] |
| 485 | Unit *allocres=NULL; // -> allocated result, iff allocated |
| 486 | Int d=0; // count of digits found in decimal part |
| 487 | const char *dotchar=NULL; // where dot was found |
| 488 | const char *cfirst=chars; // -> first character of decimal part |
| 489 | const char *last=NULL; // -> last digit of decimal part |
| 490 | const char *c; // work |
| 491 | Unit *up; // .. |
| 492 | #if DECDPUN>1 |
| 493 | Int cut, out; // .. |
| 494 | #endif |
| 495 | Int residue; // rounding residue |
| 496 | uInt status=0; // error code |
| 497 | |
| 498 | #if DECCHECK |
| 499 | if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set)) |
| 500 | return decNumberZero(dn); |
| 501 | #endif |
| 502 | |
| 503 | do { // status & malloc protection |
| 504 | for (c=chars;; c++) { // -> input character |
| 505 | if (*c>='0' && *c<='9') { // test for Arabic digit |
| 506 | last=c; |
| 507 | d++; // count of real digits |
| 508 | continue; // still in decimal part |
| 509 | } |
| 510 | if (*c=='.' && dotchar==NULL) { // first '.' |
| 511 | dotchar=c; // record offset into decimal part |
| 512 | if (c==cfirst) cfirst++; // first digit must follow |
| 513 | continue;} |
| 514 | if (c==chars) { // first in string... |
| 515 | if (*c=='-') { // valid - sign |
| 516 | cfirst++; |
| 517 | bits=DECNEG; |
| 518 | continue;} |
| 519 | if (*c=='+') { // valid + sign |
| 520 | cfirst++; |
| 521 | continue;} |
| 522 | } |
| 523 | // *c is not a digit, or a valid +, -, or '.' |
| 524 | break; |
| 525 | } // c |
| 526 | |
| 527 | if (last==NULL) { // no digits yet |
| 528 | status=DEC_Conversion_syntax;// assume the worst |
| 529 | if (*c=='\0') break; // and no more to come... |
| 530 | #if DECSUBSET |
| 531 | // if subset then infinities and NaNs are not allowed |
| 532 | if (!set->extended) break; // hopeless |
| 533 | #endif |
| 534 | // Infinities and NaNs are possible, here |
| 535 | if (dotchar!=NULL) break; // .. unless had a dot |
no test coverage detected