tst-getdate.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Test for getdate.
  2. Copyright (C) 2000-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <array_length.h>
  16. #include <stdbool.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <support/check.h>
  21. #include <support/temp_file.h>
  22. #include <support/xunistd.h>
  23. #include <time.h>
  24. static const struct
  25. {
  26. const char *str;
  27. const char *tz;
  28. struct tm tm;
  29. bool time64;
  30. int err_val;
  31. bool check_tm;
  32. } tests [] =
  33. {
  34. {"21:01:10 1999-1-31", "Universal", {10, 1, 21, 31, 0, 99, 0, 30, 0},
  35. false , 0, true},
  36. {"21:01:10 1999-1-31", "Universal", {10, 1, 21, 31, 0, 99, 0, 30, 0},
  37. false , 0, true},
  38. {" 21:01:10 1999-1-31", "Universal", {10, 1, 21, 31, 0, 99, 0, 30, 0},
  39. false , 0, true},
  40. {"21:01:10 1999-1-31 ", "Universal", {10, 1, 21, 31, 0, 99, 0, 30, 0},
  41. false , 0, true},
  42. {" 21:01:10 1999-1-31 ", "Universal", {10, 1, 21, 31, 0, 99, 0, 30, 0},
  43. false , 0, true},
  44. {"21:01:10 1999-2-28", "Universal", {10, 1, 21, 28, 1, 99, 0, 58, 0},
  45. false , 0, true},
  46. {"16:30:46 2000-2-29", "Universal", {46, 30,16, 29, 1, 100, 2, 59, 0},
  47. false , 0, true},
  48. {"01-08-2000 05:06:07", "Europe/Berlin", {7, 6, 5, 1, 7, 100, 2, 213, 0},
  49. false , 0, true},
  50. {"01-08-2000 05:06:07", "Europe/Berlin", {7, 6, 5, 1, 7, 100, 2, 213, 0},
  51. false , 0, true},
  52. {"01-08-2000 a 05:06:07", "Europe/Berlin", {0, 0, 0, 0, 0, 0, 0, 0, 0},
  53. false , 7, false},
  54. {" 12 AM ", "Europe/Berlin", {0, 0, 0, 0, 0, 0, 0, 0, 0},
  55. false , 0, false},
  56. {"01-01-1900 2 PM", "Universal", {0, 0, 14, 1, 0, 0, 1, 0, 0},
  57. false, 0, true},
  58. {"12-12-1850 16h", "Universal", {0, 0, 16, 12, 11, -50, 4, 345, 0},
  59. false, 0, true},
  60. {"12/31/93 21:35", "Universal", {0, 35, 21, 31, 11, 93, 5, 364, 0},
  61. false, 0, true},
  62. /* 64 bit time_t tests. */
  63. {"21:01:10 2038-1-31", "Universal", {10, 1, 21, 31, 0, 138, 0, 30, 0},
  64. true , 0, true},
  65. {"22:01:10 2048-5-20", "Universal", {10, 1, 22, 20, 4, 148, 3, 140, 0},
  66. true , 0, true},
  67. {"01-08-2038 05:06:07", "Europe/Berlin", {7, 6, 5, 1, 7, 138, 0, 212, 0},
  68. true , 0, true},
  69. {"20-03-2050 21:30:08", "Europe/Berlin", {8, 30, 21, 20, 2, 150, 0, 78, 0},
  70. true , 0, true}
  71. };
  72. static const char *
  73. report_date_error (void)
  74. {
  75. switch (getdate_err)
  76. {
  77. case 1:
  78. return "The environment variable DATEMSK is not defined or null.";
  79. case 2:
  80. return "The template file denoted by the DATEMSK environment variable "
  81. "cannot be opened.";
  82. case 3:
  83. return "Information about the template file cannot retrieved.";
  84. case 4:
  85. return "The template file is not a regular file.\n";
  86. case 5:
  87. return "An I/O error occurred while reading the template file.";
  88. case 6:
  89. return "Not enough memory available to execute the function.";
  90. case 7:
  91. return "The template file contains no matching template.";
  92. case 8:
  93. return "The input date is invalid, but would match a template "
  94. "otherwise.";
  95. default:
  96. return "Unknown error code.";
  97. }
  98. }
  99. static char *datemsk;
  100. static const char datemskstr[] =
  101. "%H:%M:%S %F\n"
  102. "%d-%m-%Y %T\n"
  103. "%I %p\n"
  104. "%d-%m-%Y %I %p\n"
  105. "%d-%m-%Y %H%nh\n"
  106. "%D %R\n";
  107. static void
  108. do_prepare (int argc, char **argv)
  109. {
  110. int fd = create_temp_file ("tst-getdate.", &datemsk);
  111. xwrite (fd, datemskstr, sizeof (datemskstr) - 1);
  112. setenv ("DATEMSK", datemsk, 1);
  113. }
  114. #define PREPARE do_prepare
  115. static int
  116. do_test (void)
  117. {
  118. struct tm *tm;
  119. for (int i = 0; i < array_length (tests); ++i)
  120. {
  121. setenv ("TZ", tests[i].tz, 1);
  122. tm = getdate (tests[i].str);
  123. /* Only check getdate_err when tm is NULL as getdate doesn't set
  124. getdate_err on success. */
  125. if (tm == NULL)
  126. {
  127. TEST_COMPARE (getdate_err, tests[i].err_val);
  128. if (getdate_err != tests[i].err_val)
  129. printf ("%s\n", report_date_error ());
  130. }
  131. if (tests[i].err_val != 0) /* Expected failure */
  132. {
  133. TEST_VERIFY (tm == NULL);
  134. continue;
  135. }
  136. if (tests[i].check_tm)
  137. {
  138. TEST_COMPARE (tests[i].tm.tm_mon, tm->tm_mon);
  139. TEST_COMPARE (tests[i].tm.tm_year, tm->tm_year);
  140. TEST_COMPARE (tests[i].tm.tm_mday, tm->tm_mday);
  141. TEST_COMPARE (tests[i].tm.tm_hour, tm->tm_hour);
  142. TEST_COMPARE (tests[i].tm.tm_min, tm->tm_min);
  143. TEST_COMPARE (tests[i].tm.tm_sec, tm->tm_sec);
  144. TEST_COMPARE (tests[i].tm.tm_wday, tm->tm_wday);
  145. TEST_COMPARE (tests[i].tm.tm_yday, tm->tm_yday);
  146. }
  147. struct tm tms;
  148. int retval = getdate_r (tests[i].str, &tms);
  149. TEST_COMPARE (retval, tests[i].err_val);
  150. if (retval == tests[i].err_val && tests[i].check_tm)
  151. {
  152. TEST_COMPARE (tests[i].tm.tm_mon, tms.tm_mon);
  153. TEST_COMPARE (tests[i].tm.tm_year, tms.tm_year);
  154. TEST_COMPARE (tests[i].tm.tm_mday, tms.tm_mday);
  155. TEST_COMPARE (tests[i].tm.tm_hour, tms.tm_hour);
  156. TEST_COMPARE (tests[i].tm.tm_min, tms.tm_min);
  157. TEST_COMPARE (tests[i].tm.tm_sec, tms.tm_sec);
  158. TEST_COMPARE (tests[i].tm.tm_wday, tms.tm_wday);
  159. TEST_COMPARE (tests[i].tm.tm_yday, tms.tm_yday);
  160. }
  161. }
  162. return 0;
  163. }
  164. #include <support/test-driver.c>