Further WIP
This commit is contained in:
		
							parent
							
								
									0214b3b06a
								
							
						
					
					
						commit
						d1fd6453b8
					
				
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -10,6 +10,10 @@
 | 
				
			||||||
// Below are all the includes used throughout the library.
 | 
					// Below are all the includes used throughout the library.
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* options for text editors
 | 
					/* options for text editors
 | 
				
			||||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
 | 
					kate: replace-trailing-space-save true; space-indent true; tab-width 4;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ then
 | 
				
			||||||
    MONOLITHIC_SOURCE="$(echo src/libiso8601/{TopHeader,types,functions,BottomHeader}.h)"
 | 
					    MONOLITHIC_SOURCE="$(echo src/libiso8601/{TopHeader,types,functions,BottomHeader}.h)"
 | 
				
			||||||
    make_monolithic ${HDR} Ch || return 1
 | 
					    make_monolithic ${HDR} Ch || return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MONOLITHIC_SOURCE="$(echo src/libiso8601/{TopSource,c_library,calc,parser}.c)"
 | 
					    MONOLITHIC_SOURCE="$(echo src/libiso8601/{TopSource,c_library,calc,parser,print,manip}.c)"
 | 
				
			||||||
    make_monolithic ${SRC} C || return 1
 | 
					    make_monolithic ${SRC} C || return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    libiso8601_MONOLITHIC=1
 | 
					    libiso8601_MONOLITHIC=1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,24 +5,32 @@
 | 
				
			||||||
 *  http://www.gnu.org/copyleft/gpl.html for details.
 | 
					 *  http://www.gnu.org/copyleft/gpl.html for details.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// days between 0000-001 and 1970-001 (the unix epoch)
 | 
				
			||||||
 | 
					#define EPOCH_GDAY (719528)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void iso8601_now(struct iso8601_date* date, struct iso8601_details* details)
 | 
					void iso8601_now(struct iso8601_date* date, struct iso8601_details* details)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct timespec ts;
 | 
					    struct timespec ts;
 | 
				
			||||||
 | 
					    struct tm tm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    clock_gettime(CLOCK_REALTIME, &ts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // populate the `struct iso8601_date' if it was passed
 | 
					    // populate the `struct iso8601_date' if it was passed
 | 
				
			||||||
    if(date) {
 | 
					    if(date) {
 | 
				
			||||||
        clock_gettime(CLOCK_REALTIME, &ts);
 | 
					 | 
				
			||||||
        iso8601_from_ts(date, &ts);
 | 
					        iso8601_from_ts(date, &ts);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // populate the `struct iso8601_details' if it was passed
 | 
					    // populate the `struct iso8601_details' if it was passed
 | 
				
			||||||
    if(details) {
 | 
					    if(details) {
 | 
				
			||||||
        tzset();
 | 
					        memset(details, 0, sizeof(struct iso8601_details));
 | 
				
			||||||
        details->date_prec = iso8601_prec_day;
 | 
					        details->date_prec = iso8601_prec_day;
 | 
				
			||||||
        details->time_prec = iso8601_prec_secfrac;
 | 
					        details->time_prec = iso8601_prec_secfrac;
 | 
				
			||||||
        details->tz_sec = timezone;
 | 
					
 | 
				
			||||||
 | 
					        // this is silly, but it's the only way to recover the timezone
 | 
				
			||||||
 | 
					        localtime_r(&ts.tv_sec, &tm);
 | 
				
			||||||
 | 
					        details->tz_sec = tm.tm_gmtoff;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +41,7 @@ void iso8601_from_ts(struct iso8601_date* date, const struct timespec* ts)
 | 
				
			||||||
    ldiv_t qr;
 | 
					    ldiv_t qr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qr = ldiv(ts->tv_sec, 86400);
 | 
					    qr = ldiv(ts->tv_sec, 86400);
 | 
				
			||||||
    date->day = /* XXX days between 0000-001 and 1970-001 */ + qr.quot;
 | 
					    date->day = EPOCH_GDAY + qr.quot;
 | 
				
			||||||
    date->sec = qr.rem;
 | 
					    date->sec = qr.rem;
 | 
				
			||||||
    date->nsec = ts->tv_nsec;
 | 
					    date->nsec = ts->tv_nsec;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -42,7 +50,7 @@ void iso8601_from_ts(struct iso8601_date* date, const struct timespec* ts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void iso8601_to_ts(struct timespec* ts, const struct iso8601_date* date)
 | 
					void iso8601_to_ts(struct timespec* ts, const struct iso8601_date* date)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ts->tv_sec = 86400L * date->day + date->sec;
 | 
					    ts->tv_sec = 86400L * (date->day - EPOCH_GDAY) + date->sec;
 | 
				
			||||||
    ts->tv_nsec = date->nsec;
 | 
					    ts->tv_nsec = date->nsec;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,7 +61,7 @@ void iso8601_from_time_t(struct iso8601_date* date, const time_t* t)
 | 
				
			||||||
    ldiv_t qr;
 | 
					    ldiv_t qr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qr = ldiv(*t, 86400);
 | 
					    qr = ldiv(*t, 86400);
 | 
				
			||||||
    date->day = /* XXX days between 0000-001 and 1970-001 */ + qr.quot;
 | 
					    date->day = EPOCH_GDAY + qr.quot;
 | 
				
			||||||
    date->sec = qr.rem;
 | 
					    date->sec = qr.rem;
 | 
				
			||||||
    date->nsec = 0;
 | 
					    date->nsec = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -62,8 +70,7 @@ void iso8601_from_time_t(struct iso8601_date* date, const time_t* t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void iso8601_to_time_t(time_t* t, const struct iso8601_date* date)
 | 
					void iso8601_to_time_t(time_t* t, const struct iso8601_date* date)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *t = 86400L * date->day + date->sec;
 | 
					    *t = 86400L * (date->day - EPOCH_GDAY) + date->sec;
 | 
				
			||||||
    if(date->nsec >= 500000000) ++*t;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,13 @@ int iso8601_isleap(int year);
 | 
				
			||||||
void iso8601_to_cal(int* year, int* month, int* day, const struct iso8601_date* date);
 | 
					void iso8601_to_cal(int* year, int* month, int* day, const struct iso8601_date* date);
 | 
				
			||||||
int iso8601_from_cal(struct iso8601_date* date, int year, int month, int day);
 | 
					int iso8601_from_cal(struct iso8601_date* date, int year, int month, int day);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* print.c */
 | 
				
			||||||
 | 
					void iso8601_print(char* str, int amt, const struct iso8601_date* date, 
 | 
				
			||||||
 | 
					    const struct iso8601_details* details);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* manip.c */
 | 
				
			||||||
 | 
					void iso8601_add_seconds(struct iso8601_date* date, long seconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* options for text editors
 | 
					/* options for text editors
 | 
				
			||||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
 | 
					kate: replace-trailing-space-save true; space-indent true; tab-width 4;
 | 
				
			||||||
vim: expandtab:ts=4:sw=4
 | 
					vim: expandtab:ts=4:sw=4
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					/* libiso8601/src/libiso8601/manip.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  (c)2006, Laurence Withers, <l@lwithers.me.uk>.
 | 
				
			||||||
 | 
					 *  Released under the GNU GPLv2. See file COPYING or
 | 
				
			||||||
 | 
					 *  http://www.gnu.org/copyleft/gpl.html for details.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void iso8601_add_seconds(struct iso8601_date* date, long seconds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ldiv_t qr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch(date->sec) {
 | 
				
			||||||
 | 
					    case 86400:
 | 
				
			||||||
 | 
					    case 86401:
 | 
				
			||||||
 | 
					        --date->sec; 
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    qr = ldiv(seconds + date->sec, 86400);
 | 
				
			||||||
 | 
					    date->day += qr.quot;
 | 
				
			||||||
 | 
					    date->sec = qr.rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* options for text editors
 | 
				
			||||||
 | 
					kate: replace-trailing-space-save true; space-indent true; tab-width 4;
 | 
				
			||||||
 | 
					vim: expandtab:ts=4:sw=4
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,154 @@
 | 
				
			||||||
 | 
					/* libiso8601/src/libiso8601/print.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  (c)2006, Laurence Withers, <l@lwithers.me.uk>.
 | 
				
			||||||
 | 
					 *  Released under the GNU GPLv2. See file COPYING or
 | 
				
			||||||
 | 
					 *  http://www.gnu.org/copyleft/gpl.html for details.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct iso8601_details _default_details = {
 | 
				
			||||||
 | 
					    iso8601_prec_day,
 | 
				
			||||||
 | 
					    iso8601_prec_sec,
 | 
				
			||||||
 | 
					    1,
 | 
				
			||||||
 | 
					    0
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void iso8601_print(char* str, int amt, const struct iso8601_date* date, 
 | 
				
			||||||
 | 
					    const struct iso8601_details* details)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int y, m, d, ret, extended;
 | 
				
			||||||
 | 
					    struct iso8601_date dttz;
 | 
				
			||||||
 | 
					    double frac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // use default details if none provided
 | 
				
			||||||
 | 
					    if(!details) details = &_default_details;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // adjust output for timezone
 | 
				
			||||||
 | 
					    dttz = *date;
 | 
				
			||||||
 | 
					    iso8601_add_seconds(&dttz, details->tz_sec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // determine whether or not to force extended output
 | 
				
			||||||
 | 
					    iso8601_to_cal(&y, &m, &d, &dttz);
 | 
				
			||||||
 | 
					    extended = details->extended || y < 0 || y > 9999;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch(details->date_prec) {
 | 
				
			||||||
 | 
					    case iso8601_prec_year:
 | 
				
			||||||
 | 
					        if(y < 0) snprintf(str, amt, "%05d", y);
 | 
				
			||||||
 | 
					        else snprintf(str, amt, "%04d", y);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_month:
 | 
				
			||||||
 | 
					        iso8601_to_cal(&y, &m, &d, &dttz);
 | 
				
			||||||
 | 
					        if(y < 0) snprintf(str, amt, "%05d-%02d", y, m);
 | 
				
			||||||
 | 
					        else snprintf(str, amt, extended ? "%04d-%02d" : "%04d%02d", y, m);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_day:
 | 
				
			||||||
 | 
					        iso8601_to_cal(&y, &m, &d, &dttz);
 | 
				
			||||||
 | 
					        if(y < 0) ret = snprintf(str, amt, "%05d-%02d-%02d", y, m, d);
 | 
				
			||||||
 | 
					        ret = snprintf(str, amt, extended ? "%04d-%02d-%02d" : "%04d%02d%02d", y, m, d);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        fprintf(stderr, "<<< NOT IMPLEMENTED >>>\n");
 | 
				
			||||||
 | 
					        abort();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(ret < 1 || ret >= amt) return;
 | 
				
			||||||
 | 
					    str += ret;
 | 
				
			||||||
 | 
					    amt -= ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch(dttz.sec) {
 | 
				
			||||||
 | 
					    case 86400:
 | 
				
			||||||
 | 
					        y = 23;
 | 
				
			||||||
 | 
					        m = 59;
 | 
				
			||||||
 | 
					        d = 60;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case 86401:
 | 
				
			||||||
 | 
					        y = 24;
 | 
				
			||||||
 | 
					        m = 0;
 | 
				
			||||||
 | 
					        d = 0;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        y = dttz.sec / 3600;
 | 
				
			||||||
 | 
					        dttz.sec -= y * 3600;
 | 
				
			||||||
 | 
					        m = dttz.sec / 60;
 | 
				
			||||||
 | 
					        dttz.sec -= m * 60;
 | 
				
			||||||
 | 
					        d = dttz.sec;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch(details->time_prec) {
 | 
				
			||||||
 | 
					    case iso8601_prec_none:
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_hour:
 | 
				
			||||||
 | 
					        ret = snprintf(str, amt, "T%02d", y);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_min:
 | 
				
			||||||
 | 
					        ret = snprintf(str, amt, extended ? "T%02d:%02d" : "T%02d%02d", y, m);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_sec:
 | 
				
			||||||
 | 
					        ret = snprintf(str, amt, extended ? "T%02d:%02d:%02d" : "T%02d%02d%02d", y, m, d);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_hourfrac:
 | 
				
			||||||
 | 
					        frac = y + m / 60.0 + (d + date->nsec / 1e9) / 3600.0;
 | 
				
			||||||
 | 
					        ret = snprintf(str, amt, "T%#09.6f", frac);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_minfrac:
 | 
				
			||||||
 | 
					        frac = m + (d + date->nsec / 1e9) / 60.0;
 | 
				
			||||||
 | 
					        ret = snprintf(str, amt, extended ? "T%02d:%#09.6f" : "T%02d%#09.6f", y, frac);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case iso8601_prec_secfrac:
 | 
				
			||||||
 | 
					        frac = d + date->nsec / 1e9;
 | 
				
			||||||
 | 
					        ret = snprintf(str, amt, extended ? "T%02d:%02d:%#09.6f" : "T%02d%02d%#09.6f", y, m, frac);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(ret < 1 || ret >= amt) return;
 | 
				
			||||||
 | 
					    str += ret;
 | 
				
			||||||
 | 
					    amt -= ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(details->tz_sec) {
 | 
				
			||||||
 | 
					        if(!--amt) {
 | 
				
			||||||
 | 
					            *str = 0;
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(details->tz_sec < 0) {
 | 
				
			||||||
 | 
					            *str++ = '-';
 | 
				
			||||||
 | 
					            ret = -details->tz_sec;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            *str++ = '+';
 | 
				
			||||||
 | 
					            ret = details->tz_sec;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        y = ret / 3600;
 | 
				
			||||||
 | 
					        ret -= y * 3600;
 | 
				
			||||||
 | 
					        m = ret / 60;
 | 
				
			||||||
 | 
					        ret -= m * 60;
 | 
				
			||||||
 | 
					        d = ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(d) snprintf(str, amt, extended ? "%02d:%02d:%02d" : "%02d%02d%02d", y, m, d);
 | 
				
			||||||
 | 
					        else if(m) snprintf(str, amt, extended ? "%02d:%02d" : "%02d%02d", y, m);
 | 
				
			||||||
 | 
					        else snprintf(str, amt, "%02d", y);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        *str++ = 'Z';
 | 
				
			||||||
 | 
					        if(amt > 1) *str = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* options for text editors
 | 
				
			||||||
 | 
					kate: replace-trailing-space-save true; space-indent true; tab-width 4;
 | 
				
			||||||
 | 
					vim: expandtab:ts=4:sw=4
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
| 
						 | 
					@ -8,9 +8,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct iso8601_date {
 | 
					struct iso8601_date {
 | 
				
			||||||
        uint32_t nsec;
 | 
					        int32_t nsec;
 | 
				
			||||||
        int32_t day;
 | 
					        int32_t day;
 | 
				
			||||||
        uint32_t sec;
 | 
					        int32_t sec; // special values: 86400 == leap second 23:59:60, 86401 == midnight 24:00:00
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum iso8601_date_prec {
 | 
					enum iso8601_date_prec {
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ enum iso8601_time_prec {
 | 
				
			||||||
}time_prec;
 | 
					}time_prec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct iso8601_details {
 | 
					struct iso8601_details {
 | 
				
			||||||
        uint8_t date_prec, time_prec;
 | 
					        uint8_t date_prec, time_prec, extended;
 | 
				
			||||||
        int32_t tz_sec;
 | 
					        int32_t tz_sec;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,189 @@
 | 
				
			||||||
 | 
					/* libiso8601/src/tests/printer.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  (c)2006, Laurence Withers, <l@lwithers.me.uk>.
 | 
				
			||||||
 | 
					 *  Released under the GNU GPLv2. See file COPYING or
 | 
				
			||||||
 | 
					 *  http://www.gnu.org/copyleft/gpl.html for details.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "iso8601.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_nofrac(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_sec;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_min(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_min;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_minfrac(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_minfrac;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_hour(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_hour;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_hourfrac(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_hourfrac;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_day(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_month(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->date_prec = iso8601_prec_month;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_local_year(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->date_prec = iso8601_prec_year;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_nofrac(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_sec;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_min(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_min;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_minfrac(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_minfrac;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_hour(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_hour;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_hourfrac(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_hourfrac;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_day(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->time_prec = iso8601_prec_none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_month(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->date_prec = iso8601_prec_month;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_details_utc_year(struct iso8601_details* dt_out, const struct iso8601_details* dt_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memcpy(dt_out, dt_in, sizeof(struct iso8601_details));
 | 
				
			||||||
 | 
					    dt_out->tz_sec = 0;
 | 
				
			||||||
 | 
					    dt_out->date_prec = iso8601_prec_year;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct test {
 | 
				
			||||||
 | 
					    const char* desc;
 | 
				
			||||||
 | 
					    void (*do_details)(struct iso8601_details* dt_out, const struct iso8601_details* dt_in);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const struct test tests[] = {
 | 
				
			||||||
 | 
					    { "UTC with fraction", do_details_utc },
 | 
				
			||||||
 | 
					    { "UTC without fraction", do_details_utc_nofrac },
 | 
				
			||||||
 | 
					    { "UTC minute", do_details_utc_min },
 | 
				
			||||||
 | 
					    { "UTC minute with fraction", do_details_utc_minfrac },
 | 
				
			||||||
 | 
					    { "UTC hour", do_details_utc_hour },
 | 
				
			||||||
 | 
					    { "UTC hour with fraction", do_details_utc_hourfrac },
 | 
				
			||||||
 | 
					    { "UTC day", do_details_utc_day },
 | 
				
			||||||
 | 
					    { "UTC month", do_details_utc_month },
 | 
				
			||||||
 | 
					    { "UTC year", do_details_utc_year },
 | 
				
			||||||
 | 
					    { "Local with fraction", do_details_local },
 | 
				
			||||||
 | 
					    { "Local without fraction", do_details_local_nofrac },
 | 
				
			||||||
 | 
					    { "Local minute", do_details_local_min },
 | 
				
			||||||
 | 
					    { "Local minute with fraction", do_details_local_minfrac },
 | 
				
			||||||
 | 
					    { "Local hour", do_details_local_hour },
 | 
				
			||||||
 | 
					    { "Local hour with fraction", do_details_local_hourfrac },
 | 
				
			||||||
 | 
					    { "Local day", do_details_local_day },
 | 
				
			||||||
 | 
					    { "Local month", do_details_local_month },
 | 
				
			||||||
 | 
					    { "Local year", do_details_local_year },
 | 
				
			||||||
 | 
					    { 0, 0 }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char* argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = 0;
 | 
				
			||||||
 | 
					    struct iso8601_date dt;
 | 
				
			||||||
 | 
					    struct iso8601_details details, details2;
 | 
				
			||||||
 | 
					    char buf[100], buf2[100];
 | 
				
			||||||
 | 
					    const struct test* test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(argc == 2 && !strcmp(argv[1], "--print-summary")) {
 | 
				
			||||||
 | 
					        printf("Prints the current time in various formats.\n");
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iso8601_now(&dt, &details);
 | 
				
			||||||
 | 
					    printf("%-30s  %-30s  %s\n", "Name", "Basic format", "Extended format");
 | 
				
			||||||
 | 
					    for(test = tests; test->desc; ++test) {
 | 
				
			||||||
 | 
					        test->do_details(&details2, &details);
 | 
				
			||||||
 | 
					        iso8601_print(buf, sizeof(buf), &dt, &details2);
 | 
				
			||||||
 | 
					        ++details2.extended;
 | 
				
			||||||
 | 
					        iso8601_print(buf2, sizeof(buf2), &dt, &details2);
 | 
				
			||||||
 | 
					        printf("%-30s  %-30s  %s\n", test->desc, buf, buf2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* options for text editors
 | 
				
			||||||
 | 
					kate: replace-trailing-space-save true; space-indent true; tab-width 4;
 | 
				
			||||||
 | 
					vim: expandtab:ts=4:sw=4
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
		Loading…
	
		Reference in New Issue