=head1 NAME

dt - Lightweight C library for date arithmetic and date conversion using the proleptic Gregorian calendar

=head1 FEATURES

=over 4

=item * Portable, C89

=item * No sytem calls

=item * No broken-down date structures

=item * Fast arithmetic and compact representation of dates

=item * Follows the ISO 8601 conventions

=item * Conversion between all ISO 8601 date representations

=item * Good test coverage

=back

=head1 INTRODUCTION

Dates values C<dt_t> are represented as an integer denoting the number of days 
since the zero epoch, December 31 of the year zero in the proleptic Gregorian 
calendar. The supported date range is from -5879610-06-22 (C<INT32_MIN>) 
to +5879611-07-11 (C<INT32_MAX>).

Functions provided by this library doesn't usually guard against integer
overflows, it's the callers responsibility to ensure that dates and date
arithmetic is within the supported range.

But there is a Tarantool extension mode activated if C<DT_PARSE_ISO_TNT> macro
defined, when C<dt_from_*_checked> functions become available which validate
input arguments and internally operate using 64-bit arithmetics, thus they avoid
any sort of 32-bit overflow. Use this set of functions if you need to deal with
extended years range, outside of standard [0001..9999].

=head1 FUNCTIONS

=head2 dt_from_cjdn

    dt_t dt_from_cjdn(int cjdn);

Returns a date corresponding to the given chronological Julian day number I<cjdn>.

=head2 dt_from_rdn

    dt_t dt_from_rdn(int rdn);

Returns a date corresponding to the given Rata Die number I<rdn>.

=head2 dt_from_easter

    dt_t dt_from_easter(int year, dt_computus_t computus);

Returns a date corresponding to the Easter Sunday for the given I<year>. The 
parameter I<computus> specifies the Easter calculation. Returns C<0> if the 
given year is non-positive.

I<(computus = DT_WESTERN)> 

Calculation based on the Gregorian calendar.

I<(computus = DT_ORTHODOX)> 

Calculation based on the Julian calendar with the Julian date converted to the 
equivalent Gregorian date.

B<Example:>

    /* Easter Sunday */
    dt = dt_from_easter(2012, DT_WESTERN);

    /* Good Friday, 2 days before Easter */
    dt = dt_from_easter(2012, DT_WESTERN) - 2;

    /* Pentecost, 49 days after Easter (50th day of Easter) */
    dt = dt_from_easter(2012, DT_WESTERN) + 49;

=head2 dt_from_struct_tm

    dt_t dt_from_struct_tm(const struct tm *tm);

Returns a date corresponding to the given structure I<tm>. Folowing members 
of the I<tm> structure must be set: I<tm_year>, I<tm_mon> and I<tm_mday>.
The members I<tm_mon> and I<tm_mday> may be outside usual range and will be 
normalized during the conversion.

=head2 dt_from_yd

    dt_t dt_from_yd(int year, int day);

Returns a date corresponding to the given ordinal date: I<year> and I<day>
of the year (1-366). The I<day> may be outside usual range and will be normalized 
during the conversion.

=head2 dt_from_ymd

    dt_t dt_from_ymd(int year, int month, int day);

Returns a date corresponding to the given calendar date: I<year>, I<month> 
of the year (1-12), and I<day> of the month (1-31). The I<month> and I<day> may 
be outside their usual ranges and will be normalized during the conversion. 
For example, January 32 converts to February 1.

=head2 dt_from_ywd

    dt_t dt_from_ywd(int year, int week, int day);

Returns a date corresponding to the given week date: I<year>, I<week> of 
the year (1-53), and I<day> of the week (1-7). The I<week> and I<day> may be 
outside their usual ranges and will be normalized during the conversion. 

=head2 dt_from_yqd

    dt_t dt_from_yqd(int year, int quarter, int day);

Returns a date corresponding to the given quarter date: I<year>, I<quarter> 
of the year (1-4), and I<day> of the quarter (1-92). The I<quarter> and I<day> may 
be outside their usual ranges and will be normalized during the conversion.

=head2 dt_valid_yd

    bool dt_valid_yd(int year, int day);

Returns a boolean indicating whether or not the given ordinal date: I<year> and I<day>
of the year constitute a valid date.

=head2 dt_valid_ymd

    bool dt_valid_ymd(int year, int month, int day);

Returns a boolean indicating whether or not the given calendar date: I<year>, 
I<month> of the year and I<day> of the month constitute a valid date.

=head2 dt_valid_yqd

    bool dt_valid_yqd(int year, int quarter, int day);

Returns a boolean indicating whether or not the given quarter date: I<year>, 
I<quarter> of the year and I<day> of the quarter constitute a valid date.

=head2 dt_valid_ywd

    bool dt_valid_ywd(int year, int week, int day);

Returns a boolean indicating whether or not the given week date: I<year>, 
I<week> of the year and I<day> of the week constitute a valid date.

=head2 dt_from_yd_checked

    bool     dt_from_yd_checked (int y, int d, dt_t *val);

Returns a boolean indicating whether or not the given ordinal date: I<year>
and I<day> of the year constitute a valid date.

If input data is valid then return value is passed via C<val> pointer.

=head2 dt_from_ymd_checked

    bool     dt_from_ymd_checked(int y, int m, int d, dt_t *val);

Returns a boolean indicating whether or not the given calendar date: I<year>,
I<month> of the year and I<day> of the month constitute a valid date.

If input data is valid then return value is passed via C<val> pointer.

=head2 dt_from_yqd_checked

    bool     dt_from_yqd_checked(int y, int q, int d, dt_t *val);

Returns a boolean indicating whether or not the given quarter date: I<year>,
I<quarter> of the year and I<day> of the quarter constitute a valid date.

If input data is valid then return value is passed via C<val> pointer.

=head2 dt_from_ywd_checked

    bool     dt_from_ywd_checked(int y, int w, int d, dt_t *val);

Returns a boolean indicating whether or not the given week date: I<year>,
I<week> of the year and I<day> of the week constitute a valid date.

If input data is valid then return value is passed via C<val> pointer.

=head2 dt_to_struct_tm

    void dt_to_struct_tm(dt_t dt, struct tm *tm);

Converts the given date I<dt> to a broken down time I<struct *tm>. 
Following members of the I<tm> structure are set: I<tm_year>, I<tm_mon>, 
I<tm_mday>, I<tm_wday> and I<tm_yday>.

=head2 dt_to_yd

    void dt_to_yd(dt_t dt, int *year, int *day);

Converts the given date I<dt> to the corresponding ordinal date: I<year> 
and I<day> of the year (1-366). The pointer parameters may be C<NULL> for any 
of the results that are not required.

=head2 dt_to_ymd

    void dt_to_ymd(dt_t dt, int *year, int *month, int *day);

Converts the given date I<dt> to the corresponding calendar date: I<year>, 
I<month> of the year (1-12) and I<day> of the month (1-31). The pointer 
parameters may be C<NULL> for any of the results that are not required.

=head2 dt_to_yqd

    void dt_to_yqd(dt_t dt, int *year, int *quarter, int *day);

Converts the given date I<dt> to the corresponding quarter date: I<year>, 
I<quarter> of the year (1-4) and I<day> of the quarter (1-92). The pointer 
parameters may be C<NULL> for any of the results that are not required.

=head2 dt_to_ywd

    void dt_to_ywd(dt_t dt, int *year, int *week, int *day);

Converts the given date I<dt> to the corresponding week date: I<year>, 
I<week> of the year (1-53) and I<day> of the week (1=Monday to 7=Sunday). 
The pointer parameters may be C<NULL> for any of the results that are not required.

=head2 dt_cjdn

    int dt_cjdn(dt_t dt);

Returns the chronological Julian day number for the given date I<dt>.

=head2 dt_rdn

    int dt_rdn(dt_t dt);

Returns the Rata Die number for the given date I<dt>.

=head2 dt_year

    int dt_year(dt_t dt);

Returns the year for the given date I<dt>.

=head2 dt_quarter

    int dt_quarter(dt_t dt);

Returns the quarter of the year (1-4) for the given date I<dt>.

=head2 dt_month

    int dt_month(dt_t dt);

Returns the month of the year (1-12) for the given date I<dt>.

=head2 dt_doy

    int dt_doy(dt_t dt);

Returns the day of the year (1-366) for the given date I<dt>.

=head2 dt_doq

    int dt_doq(dt_t dt);

Returns the day of the quarter (1-92) for the given date I<dt>.

=head2 dt_dom

    int dt_dom(dt_t dt);

Returns the day of the month (1-31) for the given date I<dt>.

=head2 dt_dow

    int dt_dow(dt_t dt);

Returns the day of the week (1=Monday to 7=Sunday) for the given date I<dt>.

=head2 dt_woy

    int dt_woy(dt_t dt);

Returns the week of the year (1-53) for the given date I<dt>.

=head2 dt_yow

    int dt_yow(dt_t dt);

Returns the year of the week for the given date I<dt>.

=head2 dt_start_of_year

    dt_t dt_start_of_year(dt_t dt, int offset);

Returns a date set to the first day of the year for the given date I<dt>. 
The parameter I<offset> specifies the number of years before (negative) or 
after (positive) the given date.

=head2 dt_start_of_quarter

    dt_t dt_start_of_quarter(dt_t dt, int offset);

Returns a date set to the first day of the quarter for the given date I<dt>. 
The parameter I<offset> specifies the number of quarters before (negative) or 
after (positive) the given date.

=head2 dt_start_of_month

    dt_t dt_start_of_month(dt_t dt, int offset);

Returns a date set to the first day of the month for the given date I<dt>. 
The parameter I<offset> specifies the number of months before (negative) or 
after (positive) the given date.

=head2 dt_start_of_week

    dt_t dt_start_of_week(dt_t dt, dt_dow_t first);

Returns a date set to the first day of the week for the given date I<dt>. The 
parameter I<first> specifies the first day of the week.

=head2 dt_end_of_year

    dt_t dt_end_of_year(dt_t dt, int offset);

Returns a date set to the last day of the year for the given date I<dt>. The 
parameter I<offset> specifies the number of years before (negative) or after 
(positive) the given date.

=head2 dt_end_of_quarter

    dt_t dt_end_of_quarter(dt_t dt, int offset);

Returns a date set to the last day of the quarter for the given date I<dt>. The 
parameter I<offset> specifies the number of quarters before (negative) or after 
(positive) the given date.

=head2 dt_end_of_month

    dt_t dt_end_of_month(dt_t dt, int offset);

Returns a date set to the last day of the month for the given date I<dt>. The 
parameter I<offset> specifies the number of months before (negative) or after 
(positive) the given date.

=head2 dt_end_of_week

    dt_t dt_end_of_week(dt_t dt, dt_dow_t first);

Returns a date set to the last day of the week for the given date I<dt>. The 
parameter I<first> specifies the first day of the week.

=head2 dt_nth_dow

    dt_t dt_nth_dow(dt_t dt, int nth, dt_dow_t day);

Returns a date set to the I<nth> occurrence of the given I<day> of week for 
given date I<dt>. The parameter I<day> specifies the day of week.

B<Example:>

    /* Birthday of Martin Luther King, Jr., the third Monday in January */
    dt = dt_from_ymd(2012, 1, 1);
    dt = dt_nth_dow(dt, 3, DT_MONDAY);
    
    /* Memorial Day, the last Monday in May */
    dt = dt_from_ymd(2012, 5, 31);
    dt = dt_nth_dow(dt, -1, DT_MONDAY);
    
    /* Thanksgiving Day, the fourth Thursday in November */
    dt = dt_from_ymd(2012, 11, 1);
    dt = dt_nth_dow(dt, 4, DT_THURSDAY);
    
    /* Penultimate Monday in the second quarter */
    dt = dt_from_yqd(2012, 2, 91);
    dt = dt_nth_dow(dt, -2, DT_MONDAY);
    
    /* 50th Wednesday of the year */
    dt = dt_from_ymd(2012, 1, 1);
    dt = dt_nth_dow(dt, 50, DT_WEDNESDAY);

=head2 dt_next_dow

    dt_t dt_next_dow(dt_t dt, dt_dow_t day, bool current);

Returns a date set to the next or current day of week for the given date I<dt>. 
The parameter I<day> specifies the day of week. The parameter I<current> 
specifies whether or not the returned date must succeed the given date.

=head2 dt_prev_dow

    dt_t dt_prev_dow(dt_t dt, dt_dow_t day, bool current);

Returns a date set to the previous or current day of week for the given date 
I<dt>. The parameter I<day> specifies the day of week. The parameter I<current> 
specifies whether or not the returned date must precede the given date.

=head2 dt_next_weekday

    dt_t dt_next_weekday(dt_t dt, bool current);

Returns a date set to the next or current weekday (Monday through Friday) for
the given date I<dt>. The parameter I<current> specifies whether or not the 
returned date must succeed the given date.
   
=head2 dt_prev_weekday

    dt_t dt_prev_weekday(dt_t dt, bool current);

Returns a date set to the previous or current weekday (Monday through Friday) 
for the given date I<dt>. The parameter I<current> specifies whether or not the 
returned date must precede the given date.

=head2 dt_add_years

    dt_t dt_add_years(dt_t dt, int years, dt_adjust_t adjust);

Returns a date with the given number of I<years> added. The parameter 
I<adjust> defines the behaviour when the resulting year has one day less
than the year of the given date.

I<(adjust = DT_EXCESS)> If the resulting year has one day less than the year 
of the given date, then the result is counted forward or backward into the 
next or previous year by the excessive day. Otherwise, the result has the 
same day of year as the given date. For example:

    2012-366 + 1 year = 2014-001 *
    2011-365 + 1 year = 2012-365

I<(adjust = DT_LIMIT)> If the resulting year has one day less than the 
year of the given date, then the result is the last day of the resulting 
year. Otherwise, the result has the same day of year as the given date. 
For example:

    2012-366 + 1 year = 2013-365 *
    2011-365 + 1 year = 2012-365

I<(adjust = DT_SNAP)> If the given date is the last day of the year or if the 
resulting year has one day less than the year of the given date, then the result 
is the last day of the resulting year. Otherwise, the result has the same day 
of year as the given date. For example:

    2012-366 + 1 year = 2013-365 *
    2011-365 + 1 year = 2012-366 *

=head2 dt_add_quarters

    dt_t dt_add_quarters(dt_t dt, int quarters, dt_adjust_t adjust);

Returns a date with the given number of I<quarters> added. The parameter 
I<adjust> defines the behaviour when the resulting quarter has fewer days than 
the day of the quarter for the given date.

I<(adjust = DT_EXCESS)> If the resulting quarter has fewer days than the day of 
quarter for the given date, then the result is counted forward or backward into 
the next or previous quarter by the number of excessive days. Otherwise, the 
result has the same day of quarter as the given date. For example:

    2011-Q4-92 + 1 quarter = 2012-Q2-01 *
    2012-Q2-91 + 1 quarter = 2012-Q3-91

I<(adjust = DT_LIMIT)> If the resulting quarter has fewer days than the day of 
quarter for the given date, then the result is the last day of the resulting 
quarter. Otherwise, the result has the same day of quarter as the given date. 
For example:

    2011-Q4-92 + 1 quarter = 2012-Q1-91 *
    2012-Q2-91 + 1 quarter = 2012-Q3-91

I<(adjust = DT_SNAP)> If the given date is the last day of the quarter or if the 
resulting quarter has fewer days than the day of quarter for the given date, then 
the result is the last day of the resulting quarter. Otherwise, the result has 
the same day of quarter as the given date. For example:

    2011-Q4-92 + 1 quarter = 2012-Q1-91 *
    2012-Q2-91 + 1 quarter = 2012-Q3-92 *

=head2 dt_add_months

    dt_t dt_add_months(dt_t dt, int months, dt_adjust_t adjust);

Returns a date with the given numbers of I<months> added. The parameter 
I<adjust> defines the behaviour when the resulting month has fewer days than 
the day of the month for the given date. 

I<(adjust = DT_EXCESS)> If the resulting month has fewer days than the day of 
month for the given date, then the result is counted forward or backward into 
the next or previous month by the number of excessive days. Otherwise, the 
result has the same day of month as the given date. For example:

    2012-01-31 + 1 month = 2012-03-02 *
    2012-02-29 + 1 month = 2012-03-29

I<(adjust = DT_LIMIT)> If the resulting month has fewer days than the day of 
month for the given date, then the result is the last day of the resulting 
month. Otherwise, the result has the same day of month as the given date. 
For example:

    2012-01-31 + 1 month = 2012-02-29 *
    2012-02-29 + 1 month = 2012-03-29

I<(adjust = DT_SNAP)> If the given date is the last day of the month or if the 
resulting month has fewer days than the day of month for the given date, then 
the result is the last day of the resulting month. Otherwise, the result has 
the same day of month as the given date. For example:

    2012-01-31 + 1 month = 2012-02-29 *
    2012-02-29 + 1 month = 2012-03-31 *

=head2 dt_add_weekdays

    dt_t dt_add_weekdays(dt_t dt, int weekdays);

Returns a date with the given number of I<weekdays> (Monday through Friday) 
added.

=head2 dt_delta_yd

    void dt_delta_yd(dt_t start, dt_t end, int *years, int *days);

Computes the difference between the given dates I<start> and I<end> in terms of
years and days. If I<start> is earlier than I<end>, then the result is positive. 
If I<start> is later than I<end>, then the result is negative. The sign will be 
the same in each of I<years> and I<days>. The pointer parameters may be C<NULL> 
for any of the results that are not required. For example the difference between 
2012-140 and 2013-150 is 1 year and 10 days; the difference between 2012-160 and 
2013-150 is 0 years and 356 days.

=head2 dt_delta_ymd

    void dt_delta_ymd(dt_t start, dt_t end, int *years, int *months, int *days);

Computes the difference between the given dates I<start> and I<end> in terms of
years, months and days. If I<start> is earlier than I<end>, then the result is 
positive. If I<start> is later than I<end>, then the result is negative. The 
sign will be the same in each of I<years>, I<months> and I<days>. The pointer 
parameters may be C<NULL> for any of the results that are not required. For 
example the difference between 2012-02-10 and 2013-10-20 is 1 year, 8 months 
and 10 days.

=head2 dt_delta_yqd

    void dt_delta_yqd(dt_t start, dt_t end, int *years, int *quarters, int *days);

Computes the difference between the given dates I<start> and I<end> in terms of
years, quarters and days. If I<start> is earlier than I<end>, then the result is 
positive. If I<start> is later than I<end>, then the result is negative. The sign 
will be the same in each of I<years>, I<quarters> and I<days>. The pointer 
parameters may be C<NULL> for any of the results that are not required. For 
example the difference between 2012-Q1-10 and 2013-Q4-20 is 1 year, 3 quarters 
and 10 days.

=head2 dt_delta_years

    int dt_delta_years(dt_t start, dt_t end, bool complete);

Returns the difference between the given dates I<start> and I<end> in years. 
The parameter I<complete> specifies whether or not only complete years should
be calculated. A year is considered to be complete if the day of the year of 
the I<end> date is greater than or equal to the day of the year of the I<start>
date. If I<start> is earlier than I<end>, then the result is positive. If 
I<start> is later than I<end>, then the result is negative. For example the 
difference between 2011-12-31 and 2012-01-01 is 1 when C<complete> is false and
0 when C<complete> is true.

=head2 dt_delta_quarters

    int dt_delta_quarters(dt_t start, dt_t end, bool complete);

Returns the difference between the given dates I<start> and I<end> in quarters.
The parameter I<complete> specifies whether or not only complete years should
be calculated. A quarter is considered to be complete if the day of the quarter 
of the I<end> date is greater than or equal to the day of the quarter of the 
I<start> date. If I<start> is earlier than I<end>, then the result is positive. 
If I<start> is later than I<end>, then the result is negative.

=head2 dt_delta_months

    int dt_delta_months(dt_t start, dt_t end, bool complete);

Returns the difference between the given dates I<start> and I<end> in months.
The parameter I<complete> specifies whether or not only complete years should
be calculated. A month is considered to be complete if the day of the month of 
the I<end> date is greater than or equal to the day of the month of the I<start> 
date. If I<start> is earlier than I<end>, then the result is positive. If 
I<start> is later than I<end>, then the result is negative. For example the 
difference between 2012-01-25 and 2012-02-01 is 1 when C<complete> is false and
0 when C<complete> is true; the delta between 2012-01-01 and 2012-01-31 is 0 
regardless of C<complete>.

=head2 dt_delta_weeks

    int dt_delta_weeks(dt_t start, dt_t end);

Returns the difference between the given dates I<start> and I<end> in weeks.
If I<start> is earlier than I<end>, then the result is positive. If I<start> 
is later than I<end>, then the result is negative.

=head2 dt_delta_weekdays

    int dt_delta_weekdays(dt_t start, dt_t end, bool inclusive);

Returns the number of weekdays (Monday through Friday) between the given 
dates I<start> and I<end>. The parameter I<inclusive> specifies whether the 
I<end> date should be inclusive. If I<start> is earlier than I<end>, then 
the result is positive. If I<start> is later than I<end>, then the result 
is negative.

=head2 dt_parse_string

    size_t dt_parse_string(const char *str, size_t len, dt_t *dtp);

=head2 dt_leap_year

    bool dt_leap_year(int year);

Returns a boolean indicating whether or not the given I<year> is a leap year.

=head2 dt_days_in_year

    int dt_days_in_year(int year);

Returns the number of days in the given I<year> (365-366).

=head2 dt_days_in_quarter

    int dt_days_in_quarter(int year, int quarter);

Returns the number of days in the given I<quarter> (90-92) within the given I<year>.
Returns C<0> if the given quarter is out of range (1-4).

=head2 dt_days_in_month

    int dt_days_in_month(int year, int month);

Returns the number of days in the given I<month> (28-31) within the given I<year>.
Returns C<0> if the given month is out of range (1-12).

=head2 dt_weeks_in_year

    int dt_weeks_in_year(int year);

Returns the number of weeks in the given I<year> (52-53).

=head1 TEST HARNESS

The unit tests is written in C using the Test Anything Protocol (TAP). Perl and 
the C<prove> command (provided by Perl module C<Test::Harness>) is required to 
run the harness. The version of C<Test::Harness> must be equal to or greater 
than v3.23.

    $ prove -V
    TAP::Harness v3.23 and Perl v5.14.1

=head2 Installing Test::Harness

Install using the C<cpan> client:

    $ cpan install Test::Harness

Install using the source package (L<http://search.cpan.org/dist/Test-Harness/>):

    $ tar -zxf Test-Harness-3.25.tar.gz
    $ cd Test-Harness-3.25
    $ perl Makfile.PL
    $ make
    $ make test
    $ sudo make install

=head2 Compiling and running the test harness:

    $ make test

output:

    t/yd.t ................ ok
    t/ymd.t ............... ok
    t/ymd_epochs.t ........ ok
    t/yqd.t ............... ok
    t/ywd.t ............... ok
    t/tm.t ................ ok
    t/easter_western.t .... ok
    t/easter_orthodox.t ... ok
    t/days_in_year.t ...... ok
    t/days_in_month.t ..... ok
    t/days_in_quarter.t ... ok
    t/start_of_year.t ..... ok
    t/start_of_quarter.t .. ok
    t/start_of_month.t .... ok
    t/start_of_week.t ..... ok
    t/end_of_year.t ....... ok
    t/end_of_quarter.t .... ok
    t/end_of_month.t ...... ok
    t/end_of_week.t ....... ok
    t/next_dow.t .......... ok
    t/prev_dow.t .......... ok
    t/next_weekday.t ...... ok
    t/prev_weekday.t ...... ok
    t/nth_dow.t ........... ok
    t/add_years.t ......... ok
    t/add_quarters.t ...... ok
    t/add_months.t ........ ok
    t/add_weekdays.t ...... ok
    t/delta_yd.t .......... ok
    t/delta_ymd.t ......... ok
    t/delta_yqd.t ......... ok
    t/delta_weekdays.t .... ok
    t/parse_string.t ...... ok
    t/add_workdays.t ...... ok
    t/delta_workdays.t .... ok
    t/is_holiday.t ........ ok
    t/is_workday.t ........ ok
    t/adjust.t ............ ok
    All tests successful.
    Files=38, Tests=13181,  2 wallclock secs ( 1.14 usr  0.09 sys +  0.04 cusr  0.06 csys =  1.33 CPU)
    Result: PASS

=head1 SUPPORT

=head2 Bugs / Feature Requests

Please report any bugs or feature requests through the issue tracker
at L<https://github.com/chansen/c-dt/issues>.

=head2 Source Code

This is open source software.  The code repository is available for
public review and contribution under the terms of the license.

L<https://github.com/chansen/c-dt>

  git clone https://github.com/chansen/c-dt.git

=head1 ACKNOWLEDGEMENTS

Easter algorithms by Al Petrofsky, San Mateo County, California, U.S.A. L<http://petrofsky.org/>.

The TAP producer which is bundled with this library is written by Jake Gelbman
L<https://github.com/zorgnax/libtap>.

=head1 AUTHOR

Christian Hansen <chansen@cpan.org>

=head1 COPYRIGHT AND LICENSE

Copyright (c) 2012-2015 Christian Hansen

This is free software; you can redistribute it and/or modify it under the terms 
of The BSD 2-Clause License.

