From: Chris Sosnin <k.sosnin@tarantool.org> To: tarantool-patches@dev.tarantool.org, sergepetrenko@tarantool.org, v.shpilevoy@tarantool.org Subject: [Tarantool-patches] [PATCH v2 1/2] Refactor decNumberFromString Date: Wed, 24 Jun 2020 19:53:31 +0300 [thread overview] Message-ID: <7e17dc729687c7c61da5f761e4302e6e78b9d01f.1593017012.git.k.sosnin@tarantool.org> (raw) In-Reply-To: <cover.1593017012.git.k.sosnin@tarantool.org> Allow parsing a valid beginning of the string to unify the behavior with strto* functions. Needed for tarantool/tarantool#4415 --- decNumber.c | 19 +++++++++++-------- decNumber.h | 26 +++++++++++++------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/decNumber.c b/decNumber.c index 85deb13..e248656 100644 --- a/decNumber.c +++ b/decNumber.c @@ -545,7 +545,7 @@ char * decNumberToEngString(const decNumber *dn, char *string){ /* */ /* If bad syntax is detected, the result will be a quiet NaN. */ /* ------------------------------------------------------------------ */ -decNumber * decNumberFromString(decNumber *dn, const char chars[], +const char * decNumberFromString(decNumber *dn, const char chars[], decContext *set) { Int exponent=0; // working exponent [assume 0] uByte bits=0; // working flags [assume +ve] @@ -557,6 +557,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], const char *dotchar=NULL; // where dot was found const char *cfirst=chars; // -> first character of decimal part const char *last=NULL; // -> last digit of decimal part + const char *end=chars; const char *c; // work Unit *up; // .. #if DECDPUN>1 @@ -649,17 +650,18 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], else if (*c!='\0') { // more to process... // had some digits; exponent is only valid sequence now + status=0; // we have a number already + end=c; // backup for invalid exponent Flag nege; // 1=negative exponent const char *firstexp; // -> first significant exponent digit - status=DEC_Conversion_syntax;// assume the worst - if (*c!='e' && *c!='E') break; + if (*c!='e' && *c!='E') goto finalize; /* Found 'e' or 'E' -- now process explicit exponent */ // 1998.07.11: sign no longer required nege=0; c++; // to (possible) sign if (*c=='-') {nege=1; c++;} else if (*c=='+') c++; - if (*c=='\0') break; + if (*c<'0' || *c>'9') goto finalize; for (; *c=='0' && *(c+1)!='\0';) c++; // strip insignificant zeros firstexp=c; // save exponent digit place @@ -667,8 +669,8 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], if (*c<'0' || *c>'9') break; // not a digit exponent=X10(exponent)+(Int)*c-(Int)'0'; } // c - // if not now on a '\0', *c must not be a digit - if (*c!='\0') break; + + end=c; // (this next test must be after the syntax checks) // if it was too long the exponent may have wrapped, so check @@ -678,9 +680,10 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], // [up to 1999999999 is OK, for example 1E-1000000998] } if (nege) exponent=-exponent; // was negative - status=0; // is OK } // stuff after digits + else end=c; +finalize: // Here when whole string has been inspected; syntax is good // cfirst->first digit (never dot), last->last digit (ditto) @@ -772,7 +775,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], if (allocres!=NULL) free(allocres); // drop any storage used if (status!=0) decStatus(dn, status, set); - return dn; + return end; } /* decNumberFromString */ /* ================================================================== */ diff --git a/decNumber.h b/decNumber.h index 85a3f3f..ffaa3d8 100644 --- a/decNumber.h +++ b/decNumber.h @@ -101,19 +101,19 @@ /* decNumber public functions and macros */ /* ---------------------------------------------------------------- */ /* Conversions */ - decNumber * decNumberFromInt32(decNumber *, int32_t); - decNumber * decNumberFromUInt32(decNumber *, uint32_t); - decNumber * decNumberFromInt64(decNumber *, int64_t); - decNumber * decNumberFromUInt64(decNumber *, uint64_t); - decNumber * decNumberFromString(decNumber *, const char *, decContext *); - char * decNumberToString(const decNumber *, char *); - char * decNumberToEngString(const decNumber *, char *); - uint32_t decNumberToUInt32(const decNumber *, decContext *); - uint64_t decNumberToUInt64(const decNumber *, decContext *); - int32_t decNumberToInt32(const decNumber *, decContext *); - int64_t decNumberToInt64(const decNumber *, decContext *); - uint8_t * decNumberGetBCD(const decNumber *, uint8_t *); - decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t); + decNumber * decNumberFromInt32(decNumber *, int32_t); + decNumber * decNumberFromUInt32(decNumber *, uint32_t); + decNumber * decNumberFromInt64(decNumber *, int64_t); + decNumber * decNumberFromUInt64(decNumber *, uint64_t); + const char * decNumberFromString(decNumber *, const char *, decContext *); + char * decNumberToString(const decNumber *, char *); + char * decNumberToEngString(const decNumber *, char *); + uint32_t decNumberToUInt32(const decNumber *, decContext *); + uint64_t decNumberToUInt64(const decNumber *, decContext *); + int32_t decNumberToInt32(const decNumber *, decContext *); + int64_t decNumberToInt64(const decNumber *, decContext *); + uint8_t * decNumberGetBCD(const decNumber *, uint8_t *); + decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t); /* Operators and elementary functions */ decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *); -- 2.21.1 (Apple Git-122.3)
next prev parent reply other threads:[~2020-06-24 16:53 UTC|newest] Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-06-24 16:53 [Tarantool-patches] [PATCH v2 0/2] decNumber utilites for SQL Chris Sosnin 2020-06-24 16:53 ` Chris Sosnin [this message] 2020-06-24 22:22 ` [Tarantool-patches] [PATCH v2 1/2] Refactor decNumberFromString Vladislav Shpilevoy 2020-06-25 14:21 ` Chris Sosnin 2020-06-24 16:53 ` [Tarantool-patches] [PATCH v2 2/2] Add IsInt method for checking the fractional part of a number Chris Sosnin 2020-06-24 22:23 ` Vladislav Shpilevoy 2020-06-25 14:22 ` Chris Sosnin 2020-06-25 21:04 ` [Tarantool-patches] [PATCH v2 0/2] decNumber utilites for SQL Vladislav Shpilevoy 2020-06-26 10:57 ` Serge Petrenko
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=7e17dc729687c7c61da5f761e4302e6e78b9d01f.1593017012.git.k.sosnin@tarantool.org \ --to=k.sosnin@tarantool.org \ --cc=sergepetrenko@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 1/2] Refactor decNumberFromString' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox