OpenCoverage

posixtm.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/posixtm.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* Parse dates for touch and date.-
2-
3 Copyright (C) 1989-1991, 1998, 2000-2018 Free Software Foundation, Inc.-
4-
5 This program is free software: you can redistribute it and/or modify-
6 it under the terms of the GNU General Public License as published by-
7 the Free Software Foundation; either version 3 of the License, or-
8 (at your option) any later version.-
9-
10 This program is distributed in the hope that it will be useful,-
11 but WITHOUT ANY WARRANTY; without even the implied warranty of-
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
13 GNU General Public License for more details.-
14-
15 You should have received a copy of the GNU General Public License-
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
17-
18/* Yacc-based version written by Jim Kingdon and David MacKenzie.-
19 Rewritten by Jim Meyering. */-
20-
21#include <config.h>-
22-
23#include "posixtm.h"-
24-
25#include <stdio.h>-
26#include <stdlib.h>-
27#include <sys/types.h>-
28#include <string.h>-
29-
30#if USE_UNLOCKED_IO-
31# include "unlocked-io.h"-
32#endif-
33-
34/* ISDIGIT differs from isdigit, as follows:-
35 - Its arg may be any int or unsigned int; it need not be an unsigned char-
36 or EOF.-
37 - It's typically faster.-
38 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to-
39 isdigit unless it's important to use the locale's definition-
40 of "digit" even when the host does not conform to POSIX. */-
41#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)-
42-
43/*-
44 POSIX requires:-
45-
46 touch -t [[CC]YY]mmddhhmm[.ss] FILE...-
47 8, 10, or 12 digits, followed by optional .ss-
48 (PDS_CENTURY | PDS_SECONDS)-
49-
50 touch mmddhhmm[YY] FILE... (obsoleted by POSIX 1003.1-2001)-
51 8 or 10 digits, YY (if present) must be in the range 69-99-
52 (PDS_TRAILING_YEAR | PDS_PRE_2000)-
53-
54 date mmddhhmm[[CC]YY]-
55 8, 10, or 12 digits-
56 (PDS_TRAILING_YEAR | PDS_CENTURY)-
57-
58*/-
59-
60static bool-
61year (struct tm *tm, const int *digit_pair, size_t n, unsigned int syntax_bits)-
62{-
63 switch (n)-
64 {-
65 case 1:
executed 1 time by 1 test: case 1:
Executed by:
  • touch
1
66 tm->tm_year = *digit_pair;-
67 /* Deduce the century based on the year.-
68 POSIX requires that 00-68 be interpreted as 2000-2068,-
69 and that 69-99 be interpreted as 1969-1999. */-
70 if (digit_pair[0] <= 68)
digit_pair[0] <= 68Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
0-1
71 {-
72 if (syntax_bits & PDS_PRE_2000)
syntax_bits & 8Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
0-1
73 return false;
executed 1 time by 1 test: return 0 ;
Executed by:
  • touch
1
74 tm->tm_year += 100;-
75 }
never executed: end of block
0
76 break;
never executed: break;
0
77-
78 case 2:
executed 2 times by 1 test: case 2:
Executed by:
  • touch
2
79 if (! (syntax_bits & PDS_CENTURY))
! (syntax_bits & 2)Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • touch
0-2
80 return false;
never executed: return 0 ;
0
81 tm->tm_year = digit_pair[0] * 100 + digit_pair[1] - 1900;-
82 break;
executed 2 times by 1 test: break;
Executed by:
  • touch
2
83-
84 case 0:
executed 4 times by 1 test: case 0:
Executed by:
  • touch
4
85 {-
86 time_t now;-
87 struct tm *tmp;-
88-
89 /* Use current year. */-
90 time (&now);-
91 tmp = localtime (&now);-
92 if (! tmp)
! tmpDescription
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • touch
0-4
93 return false;
never executed: return 0 ;
0
94 tm->tm_year = tmp->tm_year;-
95 }-
96 break;
executed 4 times by 1 test: break;
Executed by:
  • touch
4
97-
98 default:
never executed: default:
0
99 abort ();
never executed: abort ();
0
100 }-
101-
102 return true;
executed 6 times by 1 test: return 1 ;
Executed by:
  • touch
6
103}-
104-
105static bool-
106posix_time_parse (struct tm *tm, const char *s, unsigned int syntax_bits)-
107{-
108 const char *dot = NULL;-
109 int pair[6];-
110 int *p;-
111 size_t i;-
112-
113 size_t s_len = strlen (s);-
114 size_t len = s_len;-
115-
116 if (syntax_bits & PDS_SECONDS)
syntax_bits & 4Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
3-5
117 {-
118 dot = strchr (s, '.');
__builtin_constant_p ( '.' )Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
!__builtin_constant_p ( s )Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
( '.' ) == '\0'Description
TRUEnever evaluated
FALSEevaluated 3 times by 1 test
Evaluated by:
  • touch
0-3
119 if (dot)
dotDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 1 time by 1 test
Evaluated by:
  • touch
1-2
120 {-
121 len = dot - s;-
122 if (s_len - len != 3)
s_len - len != 3Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • touch
0-2
123 return false;
never executed: return 0 ;
0
124 }
executed 2 times by 1 test: end of block
Executed by:
  • touch
2
125 }
executed 3 times by 1 test: end of block
Executed by:
  • touch
3
126-
127 if (! (8 <= len && len <= 12 && len % 2 == 0))
8 <= lenDescription
TRUEevaluated 7 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 1 time by 1 test
Evaluated by:
  • touch
len <= 12Description
TRUEevaluated 7 times by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
len % 2 == 0Description
TRUEevaluated 7 times by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
0-7
128 return false;
executed 1 time by 1 test: return 0 ;
Executed by:
  • touch
1
129-
130 for (i = 0; i < len; i++)
i < lenDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 7 times by 1 test
Evaluated by:
  • touch
7-66
131 if (!ISDIGIT (s[i]))
!((unsigned in...]) - '0' <= 9)Description
TRUEnever evaluated
FALSEevaluated 66 times by 1 test
Evaluated by:
  • touch
0-66
132 return false;
never executed: return 0 ;
0
133-
134 len /= 2;-
135 for (i = 0; i < len; i++)
i < lenDescription
TRUEevaluated 33 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 7 times by 1 test
Evaluated by:
  • touch
7-33
136 pair[i] = 10 * (s[2*i] - '0') + s[2*i + 1] - '0';
executed 33 times by 1 test: pair[i] = 10 * (s[2*i] - '0') + s[2*i + 1] - '0';
Executed by:
  • touch
33
137-
138 p = pair;-
139 if (! (syntax_bits & PDS_TRAILING_YEAR))
! (syntax_bits & 1)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
2-5
140 {-
141 if (! year (tm, p, len - 4, syntax_bits))
! year (tm, p,..., syntax_bits)Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • touch
0-2
142 return false;
never executed: return 0 ;
0
143 p += len - 4;-
144 len = 4;-
145 }
executed 2 times by 1 test: end of block
Executed by:
  • touch
2
146-
147 /* Handle 8 digits worth of 'MMDDhhmm'. */-
148 tm->tm_mon = *p++ - 1;-
149 tm->tm_mday = *p++;-
150 tm->tm_hour = *p++;-
151 tm->tm_min = *p++;-
152 len -= 4;-
153-
154 /* Handle any trailing year. */-
155 if (syntax_bits & PDS_TRAILING_YEAR)
syntax_bits & 1Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 2 times by 1 test
Evaluated by:
  • touch
2-5
156 {-
157 if (! year (tm, p, len, syntax_bits))
! year (tm, p,..., syntax_bits)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEevaluated 4 times by 1 test
Evaluated by:
  • touch
1-4
158 return false;
executed 1 time by 1 test: return 0 ;
Executed by:
  • touch
1
159 }
executed 4 times by 1 test: end of block
Executed by:
  • touch
4
160-
161 /* Handle seconds. */-
162 if (!dot)
!dotDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 2 times by 1 test
Evaluated by:
  • touch
2-4
163 tm->tm_sec = 0;
executed 4 times by 1 test: tm->tm_sec = 0;
Executed by:
  • touch
4
164 else if (ISDIGIT (dot[1]) && ISDIGIT (dot[2]))
((unsigned int...]) - '0' <= 9)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
((unsigned int...]) - '0' <= 9)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
0-2
165 tm->tm_sec = 10 * (dot[1] - '0') + dot[2] - '0';
executed 2 times by 1 test: tm->tm_sec = 10 * (dot[1] - '0') + dot[2] - '0';
Executed by:
  • touch
2
166 else-
167 return false;
never executed: return 0 ;
0
168-
169 return true;
executed 6 times by 1 test: return 1 ;
Executed by:
  • touch
6
170}-
171-
172/* Parse a POSIX-style date, returning true if successful. */-
173-
174bool-
175posixtime (time_t *p, const char *s, unsigned int syntax_bits)-
176{-
177 struct tm tm0;-
178 struct tm tm1;-
179 struct tm const *tm;-
180 time_t t;-
181-
182 if (! posix_time_parse (&tm0, s, syntax_bits))
! posix_time_p..., syntax_bits)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • touch
FALSEevaluated 6 times by 1 test
Evaluated by:
  • touch
2-6
183 return false;
executed 2 times by 1 test: return 0 ;
Executed by:
  • touch
2
184-
185 tm1.tm_sec = tm0.tm_sec;-
186 tm1.tm_min = tm0.tm_min;-
187 tm1.tm_hour = tm0.tm_hour;-
188 tm1.tm_mday = tm0.tm_mday;-
189 tm1.tm_mon = tm0.tm_mon;-
190 tm1.tm_year = tm0.tm_year;-
191 tm1.tm_isdst = -1;-
192 t = mktime (&tm1);-
193-
194 if (t != (time_t) -1)
t != (time_t) -1Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • touch
FALSEnever evaluated
0-6
195 tm = &tm1;
executed 6 times by 1 test: tm = &tm1;
Executed by:
  • touch
6
196 else-
197 {-
198 /* mktime returns -1 for errors, but -1 is also a valid time_t-
199 value. Check whether an error really occurred. */-
200 tm = localtime (&t);-
201 if (! tm)
! tmDescription
TRUEnever evaluated
FALSEnever evaluated
0
202 return false;
never executed: return 0 ;
0
203 }
never executed: end of block
0
204-
205 /* Reject dates like "September 31" and times like "25:61".-
206 However, allow a seconds count of 60 even in time zones that do-
207 not support leap seconds, treating it as the following second;-
208 POSIX requires this. */-
209 if ((tm0.tm_year ^ tm->tm_year)
(tm0.tm_year ^... ^ tm->tm_sec)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
1-5
210 | (tm0.tm_mon ^ tm->tm_mon)
(tm0.tm_year ^... ^ tm->tm_sec)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
1-5
211 | (tm0.tm_mday ^ tm->tm_mday)
(tm0.tm_year ^... ^ tm->tm_sec)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
1-5
212 | (tm0.tm_hour ^ tm->tm_hour)
(tm0.tm_year ^... ^ tm->tm_sec)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
1-5
213 | (tm0.tm_min ^ tm->tm_min)
(tm0.tm_year ^... ^ tm->tm_sec)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
1-5
214 | (tm0.tm_sec ^ tm->tm_sec))
(tm0.tm_year ^... ^ tm->tm_sec)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • touch
FALSEevaluated 5 times by 1 test
Evaluated by:
  • touch
1-5
215 {-
216 /* Any mismatch without 60 in the tm_sec field is invalid. */-
217 if (tm0.tm_sec != 60)
tm0.tm_sec != 60Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • touch
0-1
218 return false;
never executed: return 0 ;
0
219-
220 {-
221 /* Allow times like 01:35:60 or 23:59:60. */-
222 time_t dummy;-
223 char buf[16];-
224 char *b = stpcpy (buf, s);-
225 strcpy (b - 2, "59");-
226 if (!posixtime (&dummy, buf, syntax_bits))
!posixtime (&d..., syntax_bits)Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • touch
0-1
227 return false;
never executed: return 0 ;
0
228 }-
229 }
executed 1 time by 1 test: end of block
Executed by:
  • touch
1
230-
231 *p = t;-
232 return true;
executed 6 times by 1 test: return 1 ;
Executed by:
  • touch
6
233}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2