PageRenderTime 52ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/App/UnxUtilsSrc/unxutils/sh-utils-1.13/lib/posixtm.y

https://bitbucket.org/dabomb69/bash-portable
Happy | 242 lines | 212 code | 30 blank | 0 comment | 0 complexity | a80743ca8e63474d23779d92b42c4727 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, CC-BY-SA-3.0, Unlicense, AGPL-1.0
  1. /* Parse dates for touch.
  2. Copyright (C) 1989, 1990, 1991 Free Software Foundation Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software Foundation,
  13. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. /* Written by Jim Kingdon and David MacKenzie. */
  15. %{
  16. #ifdef HAVE_CONFIG_H
  17. #include <config.h>
  18. #endif
  19. /* The following block of alloca-related preprocessor directives is here
  20. solely to allow compilation by non GNU-C compilers of the C parser
  21. produced from this file by old versions of bison. Newer versions of
  22. bison include a block similar to this one in bison.simple. */
  23. #ifdef __GNUC__
  24. #define alloca __builtin_alloca
  25. #else
  26. #ifdef HAVE_ALLOCA_H
  27. #include <alloca.h>
  28. #else
  29. #ifdef _AIX
  30. #pragma alloca
  31. #else
  32. void *alloca ();
  33. #endif
  34. #endif
  35. #endif
  36. #include <stdio.h>
  37. #include <sys/types.h>
  38. #ifdef TM_IN_SYS_TIME
  39. #include <sys/time.h>
  40. #else
  41. #include <time.h>
  42. #endif
  43. /* Some old versions of bison generate parsers that use bcopy.
  44. That loses on systems that don't provide the function, so we have
  45. to redefine it here. */
  46. #if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
  47. #define bcopy(from, to, len) memcpy ((to), (from), (len))
  48. #endif
  49. #define YYDEBUG 1
  50. /* Lexical analyzer's current scan position in the input string. */
  51. static char *curpos;
  52. /* The return value. */
  53. static struct tm t;
  54. time_t mktime ();
  55. /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
  56. as well as gratuitiously global symbol names, so we can have multiple
  57. yacc generated parsers in the same program. Note that these are only
  58. the variables produced by yacc. If other parser generators (bison,
  59. byacc, etc) produce additional global names that conflict at link time,
  60. then those parser generators need to be fixed instead of adding those
  61. names to this list. */
  62. #define yymaxdepth pt_maxdepth
  63. #define yyparse pt_parse
  64. #define yylex pt_lex
  65. #define yyerror pt_error
  66. #define yylval pt_lval
  67. #define yychar pt_char
  68. #define yydebug pt_debug
  69. #define yypact pt_pact
  70. #define yyr1 pt_r1
  71. #define yyr2 pt_r2
  72. #define yydef pt_def
  73. #define yychk pt_chk
  74. #define yypgo pt_pgo
  75. #define yyact pt_act
  76. #define yyexca pt_exca
  77. #define yyerrflag pt_errflag
  78. #define yynerrs pt_nerrs
  79. #define yyps pt_ps
  80. #define yypv pt_pv
  81. #define yys pt_s
  82. #define yy_yys pt_yys
  83. #define yystate pt_state
  84. #define yytmp pt_tmp
  85. #define yyv pt_v
  86. #define yy_yyv pt_yyv
  87. #define yyval pt_val
  88. #define yylloc pt_lloc
  89. #define yyreds pt_reds /* With YYDEBUG defined */
  90. #define yytoks pt_toks /* With YYDEBUG defined */
  91. #define yylhs pt_yylhs
  92. #define yylen pt_yylen
  93. #define yydefred pt_yydefred
  94. #define yydgoto pt_yydgoto
  95. #define yysindex pt_yysindex
  96. #define yyrindex pt_yyrindex
  97. #define yygindex pt_yygindex
  98. #define yytable pt_yytable
  99. #define yycheck pt_yycheck
  100. static int yylex ();
  101. static int yyerror ();
  102. %}
  103. %token DIGIT
  104. %%
  105. date :
  106. digitpair /* month */
  107. digitpair /* day */
  108. digitpair /* hours */
  109. digitpair /* minutes */
  110. year
  111. seconds {
  112. if ($1 >= 1 && $1 <= 12)
  113. t.tm_mon = $1 - 1;
  114. else {
  115. YYABORT;
  116. }
  117. if ($2 >= 1 && $2 <= 31)
  118. t.tm_mday = $2;
  119. else {
  120. YYABORT;
  121. }
  122. if ($3 >= 0 && $3 <= 23)
  123. t.tm_hour = $3;
  124. else {
  125. YYABORT;
  126. }
  127. if ($4 >= 0 && $4 <= 59)
  128. t.tm_min = $4;
  129. else {
  130. YYABORT;
  131. }
  132. }
  133. year : digitpair {
  134. t.tm_year = $1;
  135. /* Deduce the century based on the year.
  136. See POSIX.2 section 4.63.3. */
  137. if ($1 <= 68)
  138. t.tm_year += 100;
  139. }
  140. | digitpair digitpair {
  141. t.tm_year = $1 * 100 + $2;
  142. if (t.tm_year < 1900) {
  143. YYABORT;
  144. } else
  145. t.tm_year -= 1900;
  146. }
  147. | /* empty */ {
  148. time_t now;
  149. struct tm *tmp;
  150. /* Use current year. */
  151. time (&now);
  152. tmp = localtime (&now);
  153. t.tm_year = tmp->tm_year;
  154. }
  155. ;
  156. seconds : /* empty */ {
  157. t.tm_sec = 0;
  158. }
  159. | '.' digitpair {
  160. if ($2 >= 0 && $2 <= 61)
  161. t.tm_sec = $2;
  162. else {
  163. YYABORT;
  164. }
  165. }
  166. ;
  167. digitpair : DIGIT DIGIT {
  168. $$ = $1 * 10 + $2;
  169. }
  170. ;
  171. %%
  172. static int
  173. yylex ()
  174. {
  175. char ch = *curpos++;
  176. if (ch >= '0' && ch <= '9')
  177. {
  178. yylval = ch - '0';
  179. return DIGIT;
  180. }
  181. else if (ch == '.' || ch == 0)
  182. return ch;
  183. else
  184. return '?'; /* Cause an error. */
  185. }
  186. static int
  187. yyerror ()
  188. {
  189. return 0;
  190. }
  191. /* Parse a POSIX-style date and return it, or (time_t)-1 for an error. */
  192. time_t
  193. posixtime (s)
  194. char *s;
  195. {
  196. curpos = s;
  197. /* Let mktime decide whether it is daylight savings time. */
  198. t.tm_isdst = -1;
  199. if (yyparse ())
  200. return (time_t)-1;
  201. else
  202. return mktime (&t);
  203. }
  204. /* Parse a POSIX-style date and return it, or NULL for an error. */
  205. struct tm *
  206. posixtm (s)
  207. char *s;
  208. {
  209. if (posixtime (s) == -1)
  210. return NULL;
  211. return &t;
  212. }