OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [getdate.c] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/* Convert a string representation of time to a time value.
2
   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
   Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
5
 
6
   The GNU C Library is free software; you can redistribute it and/or
7
   modify it under the terms of the GNU Lesser General Public
8
   License as published by the Free Software Foundation; either
9
   version 2.1 of the License, or (at your option) any later version.
10
 
11
   The GNU C Library is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
   Lesser General Public License for more details.
15
 
16
   You should have received a copy of the GNU Lesser General Public
17
   License along with the GNU C Library; if not, write to the Free
18
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
   02111-1307 USA.  */
20
 
21
/*
22
FUNCTION
23
<<getdate>>,<<getdate_r>>---convert a string representation of time to a time value
24
 
25
INDEX
26
        getdate
27
INDEX
28
        getdate_r
29
 
30
ANSI_SYNOPSIS
31
        #include <time.h>
32
        struct tm *getdate(const char *<[string]>);
33
        int getdate_r(const char *<[string]>, struct tm *<[res]>);
34
 
35
TRAD_SYNOPSIS
36
        #include <time.h>
37
        struct tm *getdate(<[string]>);
38
        const char *<[string]>;
39
 
40
        int getdate_r(<[string]>, <[res]>);
41
        const char *<[string]>;
42
        struct tm *<[res]>;
43
 
44
DESCRIPTION
45
<<getdate>> reads a file which is specified by the environment variable:
46
DATEMSK.  This file contains a number of formats valid for input to the
47
<<strptime>> function.  The input <[string]> is used as input to the format
48
strings and the first valid match that occurs is used.  The resultant
49
time struct is returned.  If an error occurs, the value <<getdate_err>> is
50
set to one of the following values.
51
 
52
     1  the DATEMSK environment variable is null or undefined,
53
     2  the template file cannot be opened for reading,
54
     3  failed to get file status information,
55
     4  the template file is not a regular file,
56
     5  an error is encountered while reading the template file,
57
     6  memory allication failed (not enough memory available),
58
     7  there is no line in the template that matches the input,
59
     8  invalid input specification
60
 
61
The <<getdate_r>> routine is similar, except that it returns the error
62
code and has the <[res]> time struct pointer passed in.  <<getdate>> is
63
non-reentrant.  Applications that wish to be reentrant should use
64
<<getdate_r>> instead of <<getdate>>.
65
 
66
RETURNS
67
<<getdate>> returns a pointer to the traditional time representation
68
(<<struct tm>>).  <<getdate_r>> returns 0 if successful, otherwise it
69
returns the error code.
70
 
71
PORTABILITY
72
<<getdate>> is defined by the Single Unix specification.
73
<<getdate_r>> is a reentrant extension.
74
 
75
<<getdate>> and <<getdate_r>> optionally require <<stat>> and <<access>>.
76
*/
77
 
78
 
79
/* Modified for newlib by Jeff Johnston, June 19/2002 */
80
 
81
#include <limits.h>
82
#include <stdio.h>
83
#include <stdlib.h>
84
#include <string.h>
85
#include <time.h>
86
#include <unistd.h>
87
#include <sys/stat.h>
88
 
89
#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2
90
# define STAT stat64
91
#else
92
# define STAT stat
93
#endif
94
 
95
#define TM_YEAR_BASE 1900
96
 
97
extern ssize_t __getline (char **, size_t *, FILE *);
98
 
99
/* Prototypes for local functions.  */
100
static int first_wday (int year, int mon, int wday);
101
static int check_mday (int year, int mon, int mday);
102
 
103
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
104
 
105
/* Error code is set to one of the following values to indicate an error.
106
     1  the DATEMSK environment variable is null or undefined,
107
     2  the template file cannot be opened for reading,
108
     3  failed to get file status information,
109
     4  the template file is not a regular file,
110
     5  an error is encountered while reading the template file,
111
     6  memory allication failed (not enough memory available),
112
     7  there is no line in the template that matches the input,
113
     8  invalid input specification Example: February 31 or a time is
114
        specified that can not be represented in a time_t (representing
115
        the time in seconds since 00:00:00 UTC, January 1, 1970) */
116
 
117
/* Returns the first weekday WDAY of month MON in the year YEAR.  */
118
static int
119
first_wday (int year, int mon, int wday)
120
{
121
  struct tm tm;
122
 
123
  if (wday == INT_MIN)
124
    return 1;
125
 
126
  memset (&tm, 0, sizeof (struct tm));
127
  tm.tm_year = year;
128
  tm.tm_mon = mon;
129
  tm.tm_mday = 1;
130
  mktime (&tm);
131
 
132
  return (1 + (wday - tm.tm_wday + 7) % 7);
133
}
134
 
135
 
136
/* Returns 1 if MDAY is a valid day of the month in month MON of year
137
   YEAR, and 0 if it is not.  */
138
static int
139
check_mday (int year, int mon, int mday)
140
{
141
  switch (mon)
142
    {
143
    case 0:
144
    case 2:
145
    case 4:
146
    case 6:
147
    case 7:
148
    case 9:
149
    case 11:
150
      if (mday >= 1 && mday <= 31)
151
        return 1;
152
      break;
153
    case 3:
154
    case 5:
155
    case 8:
156
    case 10:
157
      if (mday >= 1 && mday <= 30)
158
        return 1;
159
      break;
160
    case 1:
161
      if (mday >= 1 && mday <= (isleap (year) ? 29 : 28))
162
        return 1;
163
      break;
164
    }
165
 
166
  return 0;
167
}
168
 
169
 
170
int
171
getdate_r (const char *string, struct tm *tp)
172
{
173
  FILE *fp;
174
  char *line;
175
  size_t len;
176
  char *datemsk;
177
  char *result = NULL;
178
  time_t timer;
179
  struct tm tm;
180
  struct STAT st;
181
  int mday_ok = 0;
182
 
183
  datemsk = getenv ("DATEMSK");
184
  if (datemsk == NULL || *datemsk == '\0')
185
    return 1;
186
 
187
  if (STAT (datemsk, &st) < 0)
188
    return 3;
189
 
190
  if (!S_ISREG (st.st_mode))
191
    return 4;
192
 
193
  if (access (datemsk, R_OK) < 0)
194
    return 2;
195
 
196
  /* Open the template file.  */
197
  fp = fopen (datemsk, "r");
198
  if (fp == NULL)
199
    return 2;
200
 
201
  line = NULL;
202
  len = 0;
203
  do
204
    {
205
      ssize_t n;
206
 
207
      n = __getline (&line, &len, fp);
208
      if (n < 0)
209
        break;
210
      if (line[n - 1] == '\n')
211
        line[n - 1] = '\0';
212
 
213
      /* Do the conversion.  */
214
      tp->tm_year = tp->tm_mon = tp->tm_mday = tp->tm_wday = INT_MIN;
215
      tp->tm_hour = tp->tm_sec = tp->tm_min = INT_MIN;
216
      tp->tm_isdst = -1;
217
      result = strptime (string, line, tp);
218
      if (result && *result == '\0')
219
        break;
220
    }
221
  while (!__sfeof (fp));
222
 
223
  /* Free the buffer.  */
224
  free (line);
225
 
226
  /* Check for errors. */
227
  if (__sferror (fp))
228
    {
229
      fclose (fp);
230
      return 5;
231
    }
232
 
233
  /* Close template file.  */
234
  fclose (fp);
235
 
236
  if (result == NULL || *result != '\0')
237
    return 7;
238
 
239
  /* Get current time.  */
240
  time (&timer);
241
  localtime_r (&timer, &tm);
242
 
243
  /* If only the weekday is given, today is assumed if the given day
244
     is equal to the current day and next week if it is less.  */
245
  if (tp->tm_wday >= 0 && tp->tm_wday <= 6 && tp->tm_year == INT_MIN
246
      && tp->tm_mon == INT_MIN && tp->tm_mday == INT_MIN)
247
    {
248
      tp->tm_year = tm.tm_year;
249
      tp->tm_mon = tm.tm_mon;
250
      tp->tm_mday = tm.tm_mday + (tp->tm_wday - tm.tm_wday + 7) % 7;
251
      mday_ok = 1;
252
    }
253
 
254
  /* If only the month is given, the current month is assumed if the
255
     given month is equal to the current month and next year if it is
256
     less and no year is given (the first day of month is assumed if
257
     no day is given.  */
258
  if (tp->tm_mon >= 0 && tp->tm_mon <= 11 && tp->tm_mday == INT_MIN)
259
    {
260
      if (tp->tm_year == INT_MIN)
261
        tp->tm_year = tm.tm_year + (((tp->tm_mon - tm.tm_mon) < 0) ? 1 : 0);
262
      tp->tm_mday = first_wday (tp->tm_year, tp->tm_mon, tp->tm_wday);
263
      mday_ok = 1;
264
    }
265
 
266
  /* If no hour, minute and second are given the current hour, minute
267
     and second are assumed.  */
268
  if (tp->tm_hour == INT_MIN && tp->tm_min == INT_MIN && tp->tm_sec == INT_MIN)
269
    {
270
      tp->tm_hour = tm.tm_hour;
271
      tp->tm_min = tm.tm_min;
272
      tp->tm_sec = tm.tm_sec;
273
    }
274
 
275
  /* If no date is given, today is assumed if the given hour is
276
     greater than the current hour and tomorrow is assumed if
277
     it is less.  */
278
  if (tp->tm_hour >= 0 && tp->tm_hour <= 23
279
      && tp->tm_year == INT_MIN && tp->tm_mon == INT_MIN
280
      && tp->tm_mday == INT_MIN && tp->tm_wday == INT_MIN)
281
    {
282
      tp->tm_year = tm.tm_year;
283
      tp->tm_mon = tm.tm_mon;
284
      tp->tm_mday = tm.tm_mday + ((tp->tm_hour - tm.tm_hour) < 0 ? 1 : 0);
285
      mday_ok = 1;
286
    }
287
 
288
  /* Fill in the gaps.  */
289
  if (tp->tm_year == INT_MIN)
290
    tp->tm_year = tm.tm_year;
291
  if (tp->tm_hour == INT_MIN)
292
    tp->tm_hour = 0;
293
  if (tp->tm_min == INT_MIN)
294
    tp->tm_min = 0;
295
  if (tp->tm_sec == INT_MIN)
296
    tp->tm_sec = 0;
297
 
298
  /* Check if the day of month is within range, and if the time can be
299
     represented in a time_t.  We make use of the fact that the mktime
300
     call normalizes the struct tm.  */
301
  if ((!mday_ok && !check_mday (TM_YEAR_BASE + tp->tm_year, tp->tm_mon,
302
                                tp->tm_mday))
303
      || mktime (tp) == (time_t) -1)
304
    return 8;
305
 
306
  return 0;
307
}
308
 
309
#ifndef _REENT_ONLY
310
struct tm *
311
getdate (const char *string)
312
{
313
  /* Buffer returned by getdate.  */
314
  static struct tm tmbuf;
315
  int errval = getdate_r (string, &tmbuf);
316
 
317
  if (errval != 0)
318
    {
319
      getdate_err = errval;
320
      return NULL;
321
    }
322
 
323
  return &tmbuf;
324
}
325
#endif /* _REENT_ONLY */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.