1
0

wcsftime.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include <wchar.h>
  2. #include <time.h>
  3. #include <locale.h>
  4. #include "locale_impl.h"
  5. #include "time_impl.h"
  6. size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, const struct tm *restrict tm, locale_t loc)
  7. {
  8. size_t l, k;
  9. char buf[100];
  10. wchar_t wbuf[100];
  11. wchar_t *p;
  12. const char *t_mb;
  13. const wchar_t *t;
  14. int pad, plus;
  15. unsigned long width;
  16. for (l=0; l<n; f++) {
  17. if (!*f) {
  18. s[l] = 0;
  19. return l;
  20. }
  21. if (*f != '%') {
  22. s[l++] = *f;
  23. continue;
  24. }
  25. f++;
  26. pad = 0;
  27. if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
  28. if ((plus = (*f == '+'))) f++;
  29. width = wcstoul(f, &p, 10);
  30. if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
  31. if (!width && p!=f) width = 1;
  32. } else {
  33. width = 0;
  34. }
  35. f = p;
  36. if (*f == 'E' || *f == 'O') f++;
  37. t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
  38. if (!t_mb) break;
  39. k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf);
  40. if (k == (size_t)-1) return 0;
  41. t = wbuf;
  42. if (width) {
  43. for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);
  44. width--;
  45. if (plus && tm->tm_year >= 10000-1900)
  46. s[l++] = '+';
  47. else if (tm->tm_year < -1900)
  48. s[l++] = '-';
  49. else
  50. width++;
  51. for (; width > k && l < n; width--)
  52. s[l++] = '0';
  53. }
  54. if (k >= n-l) k = n-l;
  55. wmemcpy(s+l, t, k);
  56. l += k;
  57. }
  58. if (n) {
  59. if (l==n) l=n-1;
  60. s[l] = 0;
  61. }
  62. return 0;
  63. }
  64. size_t wcsftime(wchar_t *restrict wcs, size_t n, const wchar_t *restrict f, const struct tm *restrict tm)
  65. {
  66. return __wcsftime_l(wcs, n, f, tm, CURRENT_LOCALE);
  67. }
  68. weak_alias(__wcsftime_l, wcsftime_l);