tests: Adapt utf8locale to musl
[libisds.git] / src / win32.c
blob91e90a965433e8f5aa950553a52892ab6b585ec9
1 #include <stdio.h>
2 #include <string.h>
3 #include "isds.h"
4 #include "isds_priv.h"
5 #include "utils.h"
6 #include "win32.h"
8 #if HAVE_LIBCURL
9 /* Convert UTF-8 @string representation of ISO 8601 date to @time.
10 * XXX: Not all ISO formats are supported */
11 isds_error _isds_datestring2tm(const xmlChar *string, struct tm *time) {
12 char *ptr;
13 int len, tmp;
14 if (!string || !time) return IE_INVAL;
16 memset(time, 0, sizeof(*time));
18 if (sscanf((const char*)string, "%d-%d-%d%n",
19 &time->tm_year, &time->tm_mon, &time->tm_mday, &tmp) >= 3
20 && tmp == strlen((const char*)string)) {
21 time->tm_mon--;
22 time->tm_year -= 1900;
23 return IE_SUCCESS;
26 memset(time, 0, sizeof(*time));
28 if (sscanf((const char*)string, "%d-%d%n",
29 &time->tm_year, &time->tm_yday, &tmp) >= 2
30 && tmp == strlen((const char*)string)) {
31 time->tm_yday--;
32 time->tm_year -= 1900;
33 _isds_yday2mday(time);
34 return IE_SUCCESS;
37 memset(time, 0, sizeof(*time));
38 len = strlen((const char*)string);
40 if (len < 4) {
41 return IE_NOTSUP;
44 ptr = strdup((const char*)string);
46 if (sscanf(ptr + len - 2, "%d%n", &time->tm_mday, &tmp) < 1 || tmp < 2) {
47 free(ptr);
48 return IE_NOTSUP;
51 ptr[len - 2] = '\0';
53 if (sscanf(ptr + len - 4, "%d%n", &time->tm_mon, &tmp) < 1 || tmp < 2) {
54 free(ptr);
55 return IE_NOTSUP;
58 ptr[len - 4] = '\0';
60 if (sscanf(ptr, "%d%n", &time->tm_year, &tmp) < 1 || tmp < len - 4) {
61 free(ptr);
62 return IE_NOTSUP;
65 free(ptr);
66 time->tm_mon--;
67 time->tm_year -= 1900;
68 return IE_SUCCESS;
70 #endif
72 /* MSVCRT gmtime() uses thread-local buffer. This is reentrant. */
73 _hidden struct tm *gmtime_r(const time_t *timep, struct tm *result) {
74 struct tm *buf;
76 buf = gmtime(timep);
78 if (!buf) {
79 return NULL;
82 memcpy(result, buf, sizeof(struct tm));
83 return result;
86 _hidden char *strndup(const char *s, size_t n) {
87 char *ret;
88 size_t len;
90 len = strlen(s);
91 len = len > n ? n : len;
92 ret = malloc((len + 1) * sizeof(char));
94 if (!ret) {
95 return NULL;
98 strncpy(ret, s, len);
99 ret[len] = '\0';
100 return ret;
103 /* Convert UTC broken time to time_t.
104 * @broken_utc it time in UTC in broken format. Despite its content is not
105 * touched, it'sw not-const because underlying POSIX function has non-const
106 * signature.
107 * @return (time_t) -1 in case of error */
108 _hidden time_t _isds_timegm(struct tm *broken_utc) {
109 time_t ret;
110 time_t diff;
111 struct tm broken, *tmp;
113 ret = time(0);
114 tmp = gmtime(&ret);
116 if (!tmp) {
117 return (time_t)-1;
120 tmp->tm_isdst = broken_utc->tm_isdst;
121 diff = ret - mktime(tmp);
122 memcpy(&broken, broken_utc, sizeof(struct tm));
123 broken.tm_isdst = tmp->tm_isdst; /* handle broken_utc->tm_isdst < 0 */
124 ret = mktime(&broken) + diff;
125 return ret;
128 ssize_t getline(char **bufptr, size_t *length, FILE *fp) {
129 int pos = 0;
130 char *ret = NULL;
132 if (!*bufptr || *length < 1) {
133 free(*bufptr);
134 *length = 256;
135 *bufptr = malloc(*length * sizeof(char));
138 if (!*bufptr) {
139 *length = 0;
140 return -1;
143 do {
144 if (ret) {
145 *length *= 2;
146 ret = realloc(*bufptr, *length * sizeof(char));
148 if (!ret) {
149 free(*bufptr);
150 *bufptr = NULL;
151 *length = 0;
152 return -1;
155 *bufptr = ret;
158 ret = fgets(*bufptr + pos, *length, fp);
160 if (ret) {
161 pos = strlen(*bufptr);
163 } while (ret && (*bufptr)[pos - 1] != '\n');
165 return pos || ret ? pos : -1;