File: _PDCLIB_tzset_unlocked.c

package info (click to toggle)
libconvert-binary-c-perl 0.86-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,264 kB
  • sloc: ansic: 47,836; perl: 4,980; yacc: 2,143; makefile: 61
file content (185 lines) | stat: -rw-r--r-- 3,908 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/* _PDCLIB_tzset_unlocked( void )

   This file is part of the Public Domain C Library (PDCLib).
   Permission is granted to use, modify, and / or redistribute at will.
*/

#ifndef REGTEST

#include "pdclib/_PDCLIB_tzcode.h"

#include <stdlib.h>
#include <string.h>

#ifndef TZ_ABBR_MAX_LEN
#define TZ_ABBR_MAX_LEN 16
#endif

#ifndef TZ_ABBR_CHAR_SET
#define TZ_ABBR_CHAR_SET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
#endif

#ifndef TZ_ABBR_ERR_CHAR
#define TZ_ABBR_ERR_CHAR '_'
#endif

/* This string was in the Factory zone through version 2016f.  */
#define GRANDPARENTED   "Local time zone must be set--see zic manual page"

#ifndef TZ_STRLEN_MAX
#define TZ_STRLEN_MAX 255
#endif

static char lcl_TZname[ TZ_STRLEN_MAX + 1 ];
int  lcl_is_set = 0;

static void scrub_abbrs( struct state * sp )
{
    int i;

    /* First, replace bogus characters. */
    for ( i = 0; i < sp->charcnt; ++i )
    {
        if ( strchr( TZ_ABBR_CHAR_SET, sp->chars[ i ] ) == NULL )
        {
            sp->chars[ i ] = TZ_ABBR_ERR_CHAR;
        }
    }

    /* Second, truncate long abbreviations. */
    for ( i = 0; i < sp->typecnt; ++i )
    {
        const struct ttinfo * const ttisp = &sp->ttis[ i ];
        char * cp = &sp->chars[ ttisp->desigidx ];

        if ( strlen( cp ) > TZ_ABBR_MAX_LEN && strcmp( cp, GRANDPARENTED ) != 0 )
        {
            *( cp + TZ_ABBR_MAX_LEN ) = '\0';
        }
    }
}

/* Initialize *SP to a value appropriate for the TZ setting NAME.
   Return 0 on success, an errno value on failure.
*/
static int zoneinit( struct state * sp, char const * name )
{
    if (name && ! name[0])
    {
        /* User wants it fast rather than right. */
        sp->leapcnt = 0;        /* so, we're off a little */
        sp->timecnt = 0;
        sp->typecnt = 0;
        sp->charcnt = 0;
        sp->goback = sp->goahead = false;
        _PDCLIB_init_ttinfo( &sp->ttis[ 0 ], 0, false, 0 );
        strcpy( sp->chars, gmt );
        sp->defaulttype = 0;
        return 0;
    }
    else
    {
        int err = _PDCLIB_tzload( name, sp, true );

        if ( err != 0 && name && name[ 0 ] != ':' && _PDCLIB_tzparse( name, sp, false ) )
        {
            err = 0;
        }

        if ( err == 0 )
        {
            scrub_abbrs( sp );
        }

        return err;
    }
}

static void settzname( void )
{
    struct state * const sp = &_PDCLIB_lclmem;
    int                  i;

#if HAVE_TZNAME
    tzname[ 0 ] = tzname[ 1 ] = (char *) ( sp ? wildabbr : gmt );
#endif
#if USG_COMPAT
    daylight = 0;
    timezone = 0;
#endif
#if ALTZONE
    altzone = 0;
#endif
    if ( sp == NULL )
    {
        return;
    }
    /* And to get the latest time zone abbreviations into tzname... */
    for ( i = 0; i < sp->typecnt; ++i )
    {
        const struct ttinfo * const ttisp = &sp->ttis[ i ];
        _PDCLIB_update_tzname_etc( sp, ttisp );
    }

    for ( i = 0; i < sp->timecnt; ++i )
    {
        const struct ttinfo * const ttisp = &sp->ttis[ sp->types[ i ] ];
        _PDCLIB_update_tzname_etc( sp, ttisp );
#if USG_COMPAT
        if ( ttisp->isdst )
        {
            daylight = 1;
        }
#endif
    }
}

static void tzsetlcl( char const * name )
{
    struct state * sp = &_PDCLIB_lclmem;
    int lcl = name ? strlen( name ) < sizeof lcl_TZname : -1;

    if ( lcl < 0
            ? lcl_is_set < 0
            : 0 < lcl_is_set && strcmp( lcl_TZname, name ) == 0 )
    {
        return;
    }

    if ( sp )
    {
        if ( zoneinit( sp, name ) != 0 )
        {
            zoneinit( sp, "" );
        }

        if ( 0 < lcl )
        {
            strcpy( lcl_TZname, name );
        }
    }

    settzname();
    lcl_is_set = lcl;
}

void _PDCLIB_tzset_unlocked( void )
{
    tzsetlcl( getenv( "TZ" ) );
}

#endif

#ifdef TEST

#include "_PDCLIB_test.h"

int main( void )
{
#ifndef REGTEST
#endif

    return TEST_RESULTS;
}

#endif