-size_t wcslen (const wchar_t * str) {return 0;}
-wchar_t * wcscpy (wchar_t * dst, const wchar_t * src) {return NULL;}
-wchar_t * wcsncpy (wchar_t * dst, const wchar_t * src, size_t n) {return NULL;}
-wchar_t * wcscat (wchar_t * dst, const wchar_t * src) {return NULL;}
-wchar_t * wcsncat (wchar_t * dst, const wchar_t * src, size_t n) {return NULL;}
-int wcscmp (const wchar_t * str1, const wchar_t * str2) {return 0;}
-int wcsncmp (const wchar_t * str1, const wchar_t * str2, size_t n) {return 0;}
-wchar_t * wcschr (const wchar_t * str, const wchar_t chr) {return NULL;}
-int wcscoll (const wchar_t *str1, const wchar_t * str2) {return 0;}
-size_t wcsxfrm (wchar_t * str1, const wchar_t * str2, size_t n) {return 0;}
-wchar_t * wcsrchr (const wchar_t * str, wchar_t chr) {return NULL;}
-wchar_t * wcspbrk (const wchar_t * str, const wchar_t * set) {return NULL;}
-size_t wcsspn (const wchar_t * str, const wchar_t * set) {return 0;}
-size_t wcscspn (const wchar_t * str, const wchar_t * set) {return 0;}
-wchar_t * wcsstr (const wchar_t * str, const wchar_t * pat) {return NULL;}
-wchar_t * wcstok (wchar_t * str, const wchar_t * set, wchar_t ** a) {return NULL;}
-
-unsigned long wcstoul (const wchar_t * a, wchar_t ** b, int c) {return 0;}
-double wcstod (const wchar_t * a, wchar_t ** b) {return 0.0;}
-
-long wcstol (const wchar_t * str, wchar_t ** end, int base) {return 0;}
+size_t
+wcslen (const wchar_t * str)
+{
+ size_t i;
+ for (i = 0; str[i] != 0; i ++);
+ return i;
+}
+
+wchar_t *
+wcscpy (wchar_t * dst, const wchar_t * src)
+{
+ size_t len;
+ len = wcslen (src);
+ if (len < 1) {
+ return NULL;
+ }
+ memmove (dst, src, len * sizeof (wchar_t));
+ dst[len] = 0;
+ return dst;
+}
+
+wchar_t *
+wcsncpy (wchar_t * dst, const wchar_t * src, size_t len_max)
+{
+ size_t len;
+ len = wcslen (src);
+ if (len < 1) {
+ return NULL;
+ }
+ if (len_max < len + 1) {
+ len = len_max - 1;
+ }
+ if (len > 0) {
+ memmove (dst, src, len * sizeof (wchar_t));
+ }
+ dst[len] = 0;
+ return dst;
+}
+
+wchar_t *
+wcscat (wchar_t * dst, const wchar_t * src)
+{
+ size_t len_dst;
+ len_dst = wcslen (dst);
+ return wcscpy (dst + len_dst, src);
+}
+
+wchar_t *
+wcsncat (wchar_t * dst, const wchar_t * src, size_t n)
+{
+ size_t len_dst;
+ len_dst = wcslen (dst);
+ return wcsncpy (dst + len_dst, src, n);
+}
+
+#define SYS_IS_BIGENDIAN 0
+
+#if SYS_IS_BIGENDIAN
+#define _wcmcmp(a,b,len) memcmp((a),(b),(len) * sizeof (wchar_t))
+#else // SYS_IS_BIGENDIAN
+int
+_wcmcmp (const wchar_t * str1, const wchar_t * str2, size_t len)
+{
+ size_t i;
+ for (i = 0; i < len; i ++) {
+ if (str1[i] == str2[i]) {
+ continue;
+ } else if (str1[i] < str2[i]) {
+ return -1;
+ }
+ return 1;
+ }
+ return 0;
+}
+#endif // SYS_IS_BIGENDIAN
+
+int
+wcscmp (const wchar_t * str1, const wchar_t * str2)
+{
+ int ret;
+ size_t len;
+ size_t len1;
+ size_t len2;
+ len1 = wcslen (str1);
+ len2 = wcslen (str2);
+ len = len1;
+ if (len > len2) {
+ len = len2;
+ }
+ ret = _wcmcmp (str1, str2, len);
+ if (0 == ret) {
+ if (len1 > len2) {
+ return -1;
+ } else if (len1 == len2) {
+ return 0;
+ }
+ return 1;
+ }
+ return ret;
+}
+
+int
+wcsncmp (const wchar_t * str1, const wchar_t * str2, size_t n)
+{
+ int ret;
+ size_t len;
+ size_t len1;
+ size_t len2;
+ len1 = wcslen (str1);
+ len2 = wcslen (str2);
+ len = len1;
+ if (len > len2) {
+ len = len2;
+ }
+ if (len > n) {
+ len = n;
+ }
+ ret = _wcmcmp (str1, str2, len);
+ if (0 == ret) {
+ if (len >= n) {
+ return 0;
+ }
+ if (len1 > len2) {
+ return -1;
+ } else if (len1 == len2) {
+ return 0;
+ }
+ return 1;
+ }
+ return ret;
+}
+
+wchar_t *
+wcschr (const wchar_t * str, const wchar_t chr)
+{
+ wchar_t * str2 = (wchar_t *)str;
+ size_t i;
+ size_t len;
+ len = wcslen (str2);
+ for (i = 0; i < len; i ++) {
+ if (str2[i] == chr) {
+ str2 += i;
+ return str2;
+ }
+ }
+ return NULL;
+}
+
+int wcscoll (const wchar_t *str1, const wchar_t * str2) {return wcscmp(str1, str2);}
+
+/*
+ * wcsxfrm: Transfom the wide-char str2 and place the result into the str1,
+ * return the length of the wide-char, return -1 on error.
+ */
+size_t
+wcsxfrm (wchar_t * str1, const wchar_t * str2, size_t n)
+{
+ wcsncpy (str1, str2, n);
+ return wcslen (str1);
+}
+
+wchar_t *
+wcsrchr (const wchar_t * str, wchar_t chr)
+{
+ wchar_t * str2 = (wchar_t *)str;
+ ssize_t i;
+ i = wcslen (str2);
+ for (; i >= 0; i ++) {
+ if (str2[i] == chr) {
+ str2 += i;
+ return str2;
+ }
+ }
+ return NULL;
+}
+
+wchar_t *
+wcspbrk (const wchar_t * str, const wchar_t * set)
+{
+ wchar_t * str2 = (wchar_t *)str;
+ size_t i;
+ size_t j;
+ size_t len;
+ size_t len_set;
+ len = wcslen (str2);
+ len_set = wcslen (set);
+ for (i = 0; i < len; i ++) {
+ for (j = 0; j < len_set; j ++) {
+ if (str2[i] == set[j]) {
+ str2 += i;
+ return str2;
+ }
+ }
+ }
+ return NULL;
+}
+
+/*
+ * wcsspn: compute the maxinum initial segment of the wide-char str which consists entirely of wide-char codes from the set.
+ * returnt he length of the initial substring of str
+ * examples:
+ * str="13134abcde", set="1234567890", wcsspn(str,set)==5
+ * str="abcde", set="1234567890", wcsspn(str,set)==0
+ */
+size_t
+wcsspn (const wchar_t * str, const wchar_t * set)
+{
+ size_t i;
+ size_t j;
+ size_t len;
+ size_t len_set;
+ len = wcslen (str);
+ len_set = wcslen (set);
+ for (i = 0; i < len; i ++) {
+ for (j = 0; j < len_set; j ++) {
+ if (str[i] == set[j]) {
+ break;
+ }
+ }
+ if (j >= len_set) {
+ return i;
+ }
+ }
+ return i;
+}
+
+/*
+ * wcscspn: determines the length of the initial segment of str which consists entirely of characters not found in set.
+ * examples:
+ * str="13134abcde", set="1234567890", wcsspn(str,set)==0
+ * str="abcde123", set="1234567890", wcsspn(str,set)==5
+*/
+size_t
+wcscspn (const wchar_t * str, const wchar_t * set)
+{
+ size_t i;
+ size_t j;
+ size_t len;
+ size_t len_set;
+ len = wcslen (str);
+ len_set = wcslen (set);
+ for (i = 0; i < len; i ++) {
+ for (j = 0; j < len_set; j ++) {
+ if (str[i] == set[j]) {
+ break;
+ }
+ }
+ if (j < len_set) {
+ return i;
+ }
+ }
+ return i;
+}
+
+wchar_t *
+wcsstr (const wchar_t * str, const wchar_t * pat)
+{
+ // TODO: improvement the alg for search
+ wchar_t *p;
+ p = wcschr (str, pat[0]);
+ for (; NULL != p;) {
+ if (0 == wcscmp (p, pat)) {
+ return p;
+ }
+ p = wcschr (p, pat[0]);
+ }
+ return NULL;
+}
+
+wchar_t *
+wcstok (wchar_t * str, const wchar_t * set, wchar_t ** a)
+{
+ wchar_t * p;
+ if (NULL == str) {
+ if (NULL == a) {
+ return NULL;
+ }
+ str = *a;
+ }
+ if (NULL == str) {
+ return NULL;
+ }
+ p = wcspbrk (str, set);
+ if (NULL == p) {
+ return NULL;
+ }
+ *p = 0;
+ *a = p;
+ return str;
+}
+
+#define iswblank iswspace
+//#define ULONG_MAX INT_MAX
+unsigned long
+wcstoul (const wchar_t *nptr, wchar_t **endptr, int base)
+{
+ int flg_overflow;
+ //int val_remain;
+ unsigned long val_ch;
+ unsigned long val_old;
+ unsigned long val;
+ /* check the base */
+ if ((1 == base) || (base > 36) || (base < 0)) {
+ // error
+ return 0;
+ }
+ // skip blank
+ while (iswblank (*nptr)) {nptr ++;}
+ if (0 == *nptr) {
+ return 0;
+ }
+ if (0 == base) {
+ // auto detect
+ switch (*nptr) {
+ case '0':
+ if (('x' == *(nptr + 1)) || ('X' == *(nptr + 1))) {
+ base = 16;
+ nptr += 2;
+ } else {
+ nptr += 1;
+ base = 8;
+ }
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ base = 10;
+ break;
+ }
+ } else {
+ if (16 == base) {
+ // detect if it has '0x' or '0X'
+ if (('0' == *nptr) && (('x' == *(nptr + 1)) || ('x' == *(nptr + 1)))) {
+ nptr += 2;
+ }
+ }
+ }
+ if (0 == base) {
+ // error
+ return 0;
+ }
+ val = 0;
+ val_old = 0;
+ flg_overflow = 0;
+ //val_remain = ULONG_MAX % base;
+ for (; '\0' != *nptr; nptr ++) {
+ val_ch = *nptr;
+ if (('0' <= val_ch) && (val_ch <= '9')) {
+ val_ch -= '0';
+ } else if (('a' <= val_ch) && (val_ch <= 'z')) {
+ val_ch = val_ch - 'a' + 10;
+ } else if (('A' <= val_ch) && (val_ch <= 'Z')) {
+ val_ch = val_ch - 'A' + 10;
+ } else {
+ // val_ch = base + 1;
+ break;
+ }
+ if (val_ch >= base) {
+ break;
+ }
+ if (flg_overflow) continue;
+ val_old = val;
+ val *= base;
+ val += val_ch;
+ if (val_old > val) {
+ flg_overflow = 1;
+ }
+ }
+ if (flg_overflow) {
+ val = ULONG_MAX;
+ }
+ if (0L != endptr) {
+ *endptr = (wchar_t *)nptr;
+ }
+ return val;
+}
+
+long
+wcstol (const wchar_t * str, wchar_t ** end, int base)
+{
+ int sign = 0;
+ unsigned long val0;
+ long val;
+ wchar_t ch;
+ // skip blank
+ for (; iswblank (*str); str ++) {
+ }
+ for (ch = *str; (ch == '-') || (ch == '+'); str ++) {
+ }
+ // the sign
+ if ('-' == ch) {
+ sign = 1;
+ str ++;
+ }
+ val0 = wcstoul (str, end, base);
+ if (val0 >= LONG_MAX) {
+ // overflow
+ val = LONG_MAX;
+ if (sign) {
+ val = LONG_MIN;
+ }
+ } else {
+ val = val0;
+ if (sign) {
+ val = -val0;
+ }
+ }
+ return val;
+}
+
+double
+wcstod (const wchar_t * str, wchar_t ** end)
+{
+ double val;
+ double mantissa;
+ unsigned long divisor;
+ unsigned long power;
+ int sign;
+ int sign_power;
+ wchar_t *pend;
+ wchar_t ch;
+ // skip blank
+ for (; iswblank (*str); str ++) {
+ }
+ for (ch = *str; (ch == '-') || (ch == '+'); str ++) {
+ }
+ // the sign
+ sign = 0;
+ if ('-' == ch) {
+ sign = 1;
+ str ++;
+ }
+ // skip leading zero
+ for (; '0' == (*str); str ++) {
+ }
+ val = 0.0;
+ mantissa = 0.0;
+ divisor = 0;
+ power = 0.0;
+ // integer part
+ for (ch = *str; ('0' <= ch) && (ch <= '9'); str ++) {
+ ch -= '0';
+ val *= 10;
+ val += ch;
+ }
+ // floating point & mantissa
+ if ('.' == *str) {
+ str ++;
+ for (ch = *str; ('0' <= ch) && (ch <= '9'); str ++) {
+ ch -= '0';
+ mantissa *= 10.0;
+ mantissa += ch;
+ divisor ++;
+ }
+ }
+ for (; divisor > 0; divisor --) {
+ mantissa /= 10.0;
+ }
+ val += mantissa;
+ sign_power = 0;
+ if (('e' == *str) || ('E' == *str)) {
+ str ++;
+ if ('-' == ch) {
+ sign_power = 1;
+ str ++;
+ }
+ pend = NULL;
+ power = wcstoul (str, &pend, 10);
+ if (NULL != pend) {
+ str = pend;
+ }
+ }
+ if (power > 0) {
+ if (sign_power) {
+ for (; power > 0; power --) {
+ val /= 10.0;
+ }
+ } else {
+ for (; power > 0; power --) {
+ val *= 10.0;
+ }
+ }
+ }
+ if (sign) {
+ val = - val;
+ }
+ if (end) {
+ *end = (wchar_t *)str;
+ }
+ return val;
+}
+