diff options
| author | 2015-11-13 03:19:00 +0100 | |
|---|---|---|
| committer | 2015-11-13 03:19:00 +0100 | |
| commit | 9834d85ca473ef9b229dcf4c0df758e18a4149ad (patch) | |
| tree | 1846b0867cc56321d071a642e70b6b5269e5ed90 | |
| parent | 9ca25d293fe7f8aca8d952fc7bb91464fe2d34ab (diff) | |
| download | libplist-9834d85ca473ef9b229dcf4c0df758e18a4149ad.tar.gz libplist-9834d85ca473ef9b229dcf4c0df758e18a4149ad.tar.bz2 | |
xplist: Get rid of setlocale() and use custom function to print floating point values
| -rw-r--r-- | src/xplist.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/src/xplist.c b/src/xplist.c index 1ee0138..09c1a11 100644 --- a/src/xplist.c +++ b/src/xplist.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <time.h> | 29 | #include <time.h> |
| 30 | 30 | ||
| 31 | #include <inttypes.h> | 31 | #include <inttypes.h> |
| 32 | #include <locale.h> | 32 | #include <math.h> |
| 33 | 33 | ||
| 34 | #include <libxml/xmlIO.h> | 34 | #include <libxml/xmlIO.h> |
| 35 | #include <libxml/parser.h> | 35 | #include <libxml/parser.h> |
| @@ -147,6 +147,36 @@ static struct node_t* new_uint_node(uint64_t value) | |||
| 147 | return node_create(NULL, data); | 147 | return node_create(NULL, data); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | static void dtostr(char *buf, size_t bufsize, double realval) | ||
| 151 | { | ||
| 152 | double f = realval; | ||
| 153 | double ip = 0.0; | ||
| 154 | int64_t v; | ||
| 155 | size_t len; | ||
| 156 | size_t p; | ||
| 157 | |||
| 158 | f = modf(f, &ip); | ||
| 159 | len = snprintf(buf, bufsize, "%s%"PRIi64, ((f < 0) && (ip >= 0)) ? "-" : "", (int64_t)ip); | ||
| 160 | if (len >= bufsize) { | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | if (f < 0) { | ||
| 165 | f *= -1; | ||
| 166 | } | ||
| 167 | f += 0.0000004; | ||
| 168 | |||
| 169 | p = len; | ||
| 170 | buf[p++] = '.'; | ||
| 171 | |||
| 172 | while (p < bufsize && (p <= len+6)) { | ||
| 173 | f = modf(f*10, &ip); | ||
| 174 | v = (int)ip; | ||
| 175 | buf[p++] = (v + 0x30); | ||
| 176 | } | ||
| 177 | buf[p] = '\0'; | ||
| 178 | } | ||
| 179 | |||
| 150 | static void node_to_xml(node_t* node, void *xml_struct) | 180 | static void node_to_xml(node_t* node, void *xml_struct) |
| 151 | { | 181 | { |
| 152 | struct xml_node *xstruct = NULL; | 182 | struct xml_node *xstruct = NULL; |
| @@ -194,7 +224,7 @@ static void node_to_xml(node_t* node, void *xml_struct) | |||
| 194 | case PLIST_REAL: | 224 | case PLIST_REAL: |
| 195 | tag = XPLIST_REAL; | 225 | tag = XPLIST_REAL; |
| 196 | val = (char*)malloc(64); | 226 | val = (char*)malloc(64); |
| 197 | (void)snprintf(val, 64, "%f", node_data->realval); | 227 | dtostr(val, 64, node_data->realval); |
| 198 | break; | 228 | break; |
| 199 | 229 | ||
| 200 | case PLIST_STRING: | 230 | case PLIST_STRING: |
| @@ -529,14 +559,6 @@ PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) | |||
| 529 | root_node = xmlDocGetRootElement(plist_doc); | 559 | root_node = xmlDocGetRootElement(plist_doc); |
| 530 | root.xml = root_node; | 560 | root.xml = root_node; |
| 531 | 561 | ||
| 532 | char *current_locale = setlocale(LC_NUMERIC, NULL); | ||
| 533 | char *saved_locale = NULL; | ||
| 534 | if (current_locale) { | ||
| 535 | saved_locale = strdup(current_locale); | ||
| 536 | } | ||
| 537 | if (saved_locale) { | ||
| 538 | setlocale(LC_NUMERIC, "POSIX"); | ||
| 539 | } | ||
| 540 | node_to_xml(plist, &root); | 562 | node_to_xml(plist, &root); |
| 541 | 563 | ||
| 542 | xmlChar* tmp = NULL; | 564 | xmlChar* tmp = NULL; |
| @@ -552,10 +574,6 @@ PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) | |||
| 552 | } | 574 | } |
| 553 | xmlFreeDoc(plist_doc); | 575 | xmlFreeDoc(plist_doc); |
| 554 | 576 | ||
| 555 | if (saved_locale) { | ||
| 556 | setlocale(LC_NUMERIC, saved_locale); | ||
| 557 | free(saved_locale); | ||
| 558 | } | ||
| 559 | 577 | ||
| 560 | /* free memory from parser initialization */ | 578 | /* free memory from parser initialization */ |
| 561 | xmlCleanupCharEncodingHandlers(); | 579 | xmlCleanupCharEncodingHandlers(); |
