summaryrefslogtreecommitdiffstats
path: root/libkcal/libical/vzic-1.3
diff options
context:
space:
mode:
Diffstat (limited to 'libkcal/libical/vzic-1.3')
-rw-r--r--libkcal/libical/vzic-1.3/ChangeLog57
-rw-r--r--libkcal/libical/vzic-1.3/Makefile83
-rw-r--r--libkcal/libical/vzic-1.3/Makefile.org89
-rw-r--r--libkcal/libical/vzic-1.3/README202
-rw-r--r--libkcal/libical/vzic-1.3/test-vzic.c422
-rw-r--r--libkcal/libical/vzic-1.3/vzic-dump.c409
-rw-r--r--libkcal/libical/vzic-1.3/vzic-dump.h58
-rwxr-xr-xlibkcal/libical/vzic-1.3/vzic-dump.pl222
-rwxr-xr-xlibkcal/libical/vzic-1.3/vzic-merge.pl127
-rw-r--r--libkcal/libical/vzic-1.3/vzic-output.c2325
-rw-r--r--libkcal/libical/vzic-1.3/vzic-output.h38
-rw-r--r--libkcal/libical/vzic-1.3/vzic-parse.c901
-rw-r--r--libkcal/libical/vzic-1.3/vzic-parse.h38
-rwxr-xr-xlibkcal/libical/vzic-1.3/vzic-test.pl164
-rw-r--r--libkcal/libical/vzic-1.3/vzic.c320
-rw-r--r--libkcal/libical/vzic-1.3/vzic.h196
16 files changed, 0 insertions, 5651 deletions
diff --git a/libkcal/libical/vzic-1.3/ChangeLog b/libkcal/libical/vzic-1.3/ChangeLog
deleted file mode 100644
index f2d9569e5..000000000
--- a/libkcal/libical/vzic-1.3/ChangeLog
+++ /dev/null
@@ -1,57 +0,0 @@
-2006-03-18 Damon Chaplin <damon@gnome.org>
-
- * Released Vzic 1.3
-
-2006-03-18 Damon Chaplin <damon@gnome.org>
-
- * vzic-output.c (expand_tzname): added special case for America/Nome.
- (output_rrule): made hacks a bit more general, to handle Asia/Gaza
- which now has a day=4 rule. At some point we should check what newer
- versions of Outlook can handle so we can be more accurate.
-
- * vzic-dump.c (dump_time_zone_names): try looking for timezone info
- using original and linked name.
-
- * README, *.c: fixed spelling 'compatable' -> 'compatible'.
-
- * vzic.c: patch from Jonathan Guthrie to support a --olson-dir option.
-
-2003-10-25 Damon Chaplin <damon@gnome.org>
-
- * Released Vzic 1.2
-
-2003-10-25 Damon Chaplin <damon@gnome.org>
-
- * vzic-output.c:
- * Makefile: moved the PRODUCT_ID and TZID_PREFIX settings to the
- Makefile and changed the default so people don't accidentally use
- the same IDs as Evolution.
-
- * vzic-parse.c (parse_time): substitute 23:59:59 when we read a time
- of 24:00:00. This is a bit of a kludge to avoid problems, since
- 24:00:00 is not a valid iCalendar time. Since 24:00:00 is only used
- for a few timezones in the 1930s it doesn't matter too much.
-
- To write a correct fix we'd need to review all the code that deals
- with times to see if it would be affected, e.g. a time of 24:00 on
- one day should be considered equal to 0:00 the next day.
-
- We'd also need to adjust the output times to use 0:00 the next day
- rather than 24:00. If we need to output recurrence rules that would
- be a problem, since 'last saturday at 24:00' can't be easily
- converted to another rule that uses 0:00 instead.
-
-2003-10-22 Damon Chaplin <damon@gnome.org>
-
- * Released Vzic 1.1
-
-2003-10-22 Damon Chaplin <damon@gnome.org>
-
- * vzic-parse.c (parse_time): allow a time of 24:00, as used in
- the America/Montreal and America/Toronto rules in the 1930s!
- I'm not 100% sure the rest of the code will handle this OK, but
- it only affects the 'pure' output.
-
-2003-09-01 Damon Chaplin <damon@gnome.org>
-
- * Released Vzic 1.0
diff --git a/libkcal/libical/vzic-1.3/Makefile b/libkcal/libical/vzic-1.3/Makefile
deleted file mode 100644
index 7196c1529..000000000
--- a/libkcal/libical/vzic-1.3/Makefile
+++ /dev/null
@@ -1,83 +0,0 @@
-
-#
-# You will need to set this to the directory that the Olson timezone data
-# files are in.
-#
-OLSON_DIR = ../tzdata
-
-
-# This is used as the PRODID property on the iCalendar files output.
-# It identifies the product which created the iCalendar objects.
-# So you need to substitute your own organization name and product.
-PRODUCT_ID = -//KDE//NONSGML KCal Olson-VTIMEZONE Converter//EN
-
-
-# This is used to create unique IDs for each VTIMEZONE component.
-# The prefix is put before each timezone city name. It should start and end
-# with a '/'. The first part, i.e. 'myorganization.org' below, should be
-# a unique vendor ID, e.g. use a hostname. The part after that can be
-# anything you want. We use a date and version number for libical. The %D
-# gets expanded to today's date. There is also a vzic-merge.pl which can be
-# used to merge changes into a master set of VTIMEZONEs. If a VTIMEZONE has
-# changed, it bumps the version number on the end of this prefix. */
-TZID_PREFIX = /kde.org/Olson_%D_1/
-
-
-# Set any -I include directories to find the libical header files, and the
-# libical library to link with. You only need these if you want to run the
-# tests. You may need to change the '#include <ical.h>' line at the top of
-# test-vzic.c as well.
-LIBICAL_CFLAGS =
-LIBICAL_LDADD = -lical-evolution
-
-
-#
-# You shouldn't need to change the rest of the file.
-#
-
-GLIB_CFLAGS = `pkg-config --cflags glib-2.0`
-GLIB_LDADD = `pkg-config --libs glib-2.0`
-
-CFLAGS = -g -DOLSON_DIR=\"$(OLSON_DIR)\" -DPRODUCT_ID='"$(PRODUCT_ID)"' -DTZID_PREFIX='"$(TZID_PREFIX)"' $(GLIB_CFLAGS) $(LIBICAL_CFLAGS)
-
-OBJECTS = vzic.o vzic-parse.o vzic-dump.o vzic-output.o
-
-all: vzic
-
-vzic: $(OBJECTS)
- $(CC) $(OBJECTS) $(GLIB_LDADD) -o vzic
-
-test-vzic: test-vzic.o
- $(CC) test-vzic.o $(LIBICAL_LDADD) -o test-vzic
-
-# Dependencies.
-$(OBJECTS): vzic.h
-vzic.o vzic-parse.o: vzic-parse.h
-vzic.o vzic-dump.o: vzic-dump.h
-vzic.o vzic-output.o: vzic-output.h
-
-test-parse: vzic
- ./vzic-dump.pl $(OLSON_DIR)
- ./vzic --dump --pure
- @echo
- @echo "#"
- @echo "# If either of these diff commands outputs anything there may be a problem."
- @echo "#"
- diff -ru zoneinfo/ZonesPerl zoneinfo/ZonesVzic
- diff -ru zoneinfo/RulesPerl zoneinfo/RulesVzic
-
-test-changes: vzic test-vzic
- ./test-vzic --dump-changes
- ./vzic --dump-changes --pure
- @echo
- @echo "#"
- @echo "# If this diff command outputs anything there may be a problem."
- @echo "#"
- diff -ru zoneinfo/ChangesVzic test-output
-
-clean:
- -rm -rf vzic $(OBJECTS) *~ ChangesVzic RulesVzic ZonesVzic RulesPerl ZonesPerl test-vzic test-vzic.o
-
-.PHONY: clean perl-dump test-parse
-
-
diff --git a/libkcal/libical/vzic-1.3/Makefile.org b/libkcal/libical/vzic-1.3/Makefile.org
deleted file mode 100644
index 4b5917c24..000000000
--- a/libkcal/libical/vzic-1.3/Makefile.org
+++ /dev/null
@@ -1,89 +0,0 @@
-
-#
-# You will need to set this to the directory that the Olson timezone data
-# files are in.
-#
-OLSON_DIR = /home/damon/src/olson/tzdata2006b
-
-
-# This is used as the PRODID property on the iCalendar files output.
-# It identifies the product which created the iCalendar objects.
-# So you need to substitute your own organization name and product.
-PRODUCT_ID = -//My Organization//NONSGML My Product//EN
-
-# This is what libical-evolution uses.
-#PRODUCT_ID = -//Ximian//NONSGML Evolution Olson-VTIMEZONE Converter//EN
-
-
-# This is used to create unique IDs for each VTIMEZONE component.
-# The prefix is put before each timezone city name. It should start and end
-# with a '/'. The first part, i.e. 'myorganization.org' below, should be
-# a unique vendor ID, e.g. use a hostname. The part after that can be
-# anything you want. We use a date and version number for libical. The %D
-# gets expanded to today's date. There is also a vzic-merge.pl which can be
-# used to merge changes into a master set of VTIMEZONEs. If a VTIMEZONE has
-# changed, it bumps the version number on the end of this prefix. */
-TZID_PREFIX = /myorganization.org/%D_1/
-
-# This is what libical-evolution uses.
-#TZID_PREFIX = /softwarestudio.org/Olson_%D_1/
-
-
-# Set any -I include directories to find the libical header files, and the
-# libical library to link with. You only need these if you want to run the
-# tests. You may need to change the '#include <ical.h>' line at the top of
-# test-vzic.c as well.
-LIBICAL_CFLAGS =
-LIBICAL_LDADD = -lical-evolution
-
-
-#
-# You shouldn't need to change the rest of the file.
-#
-
-GLIB_CFLAGS = `pkg-config --cflags glib-2.0`
-GLIB_LDADD = `pkg-config --libs glib-2.0`
-
-CFLAGS = -g -DOLSON_DIR=\"$(OLSON_DIR)\" -DPRODUCT_ID='"$(PRODUCT_ID)"' -DTZID_PREFIX='"$(TZID_PREFIX)"' $(GLIB_CFLAGS) $(LIBICAL_CFLAGS)
-
-OBJECTS = vzic.o vzic-parse.o vzic-dump.o vzic-output.o
-
-all: vzic
-
-vzic: $(OBJECTS)
- $(CC) $(OBJECTS) $(GLIB_LDADD) -o vzic
-
-test-vzic: test-vzic.o
- $(CC) test-vzic.o $(LIBICAL_LDADD) -o test-vzic
-
-# Dependencies.
-$(OBJECTS): vzic.h
-vzic.o vzic-parse.o: vzic-parse.h
-vzic.o vzic-dump.o: vzic-dump.h
-vzic.o vzic-output.o: vzic-output.h
-
-test-parse: vzic
- ./vzic-dump.pl $(OLSON_DIR)
- ./vzic --dump --pure
- @echo
- @echo "#"
- @echo "# If either of these diff commands outputs anything there may be a problem."
- @echo "#"
- diff -ru zoneinfo/ZonesPerl zoneinfo/ZonesVzic
- diff -ru zoneinfo/RulesPerl zoneinfo/RulesVzic
-
-test-changes: vzic test-vzic
- ./test-vzic --dump-changes
- ./vzic --dump-changes --pure
- @echo
- @echo "#"
- @echo "# If this diff command outputs anything there may be a problem."
- @echo "#"
- diff -ru zoneinfo/ChangesVzic test-output
-
-clean:
- -rm -rf vzic $(OBJECTS) *~ ChangesVzic RulesVzic ZonesVzic RulesPerl ZonesPerl test-vzic test-vzic.o
-
-.PHONY: clean perl-dump test-parse
-
-
diff --git a/libkcal/libical/vzic-1.3/README b/libkcal/libical/vzic-1.3/README
deleted file mode 100644
index 962ff2e67..000000000
--- a/libkcal/libical/vzic-1.3/README
+++ /dev/null
@@ -1,202 +0,0 @@
-
-
-VZIC README
-===========
-
-This is 'vzic', a program to convert the Olson timezone database files into
-VTIMEZONE files compatible with the iCalendar specification (RFC2445).
-
-(The name is based on the 'zic' program which converts the Olson files into
-time zone information files used by several Unix C libraries, including
-glibc. See zic(8) and tzfile(5).)
-
-
-
-REQUIREMENTS
-============
-
-You need the Olson timezone database files, which can be found at:
-
- ftp://elsie.nci.nih.gov/pub/
-
- (Old versions can be found at ftp://munnari.oz.au/pub/oldtz/)
-
-
-Vzic also uses the GLib library (for hash tables, dynamic arrays, and date
-calculations). You need version 2.0 or higher. You can get this from:
-
- http://www.gtk.org
-
-
-
-BUILDING
-========
-
-Edit the Makefile to set the OLSON_DIR, PRODUCT_ID and TZID_PREFIX variables.
-
-Then run 'make'.
-
-
-
-RUNNING
-=======
-
-Run 'vzic'.
-
-The output is placed in the zoneinfo subdirectory by default,
-but you can use the --output-dir options to set another toplevel output
-directory.
-
-By default it outputs VTIMEZONEs that try to be compatible with Outlook
-(2000, at least). Outlook can't handle certain iCalendar constructs in
-VTIMEZONEs, such as RRULEs using BYMONTHDAY, so it has to adjust the RRULEs
-slightly to get Outlook to parse them. Unfortunately this means they are
-slightly wrong. If given the --pure option, vzic outputs the exact data,
-without worrying about compatability.
-
-NOTE: We don't convert all the Olson files. We skip 'backward', 'etcetera',
-'leapseconds', 'pacificnew', 'solar87', 'solar88' and 'solar89', 'factory'
-and 'systemv', since these don't really provide any useful timezones.
-See vzic.c.
-
-
-
-MERGING CHANGES INTO A MASTER SET OF VTIMEZONES
-===============================================
-
-The Olson timezone files are updated fairly often, so we need to build new
-sets of VTIMEZONE files. Though we have to be careful to ensure that the TZID
-of updated timezones is also updated, since it must remain unique.
-
-We use a version number on the end of the TZID prefix (see the TZIDPrefix
-variable in vzic-output.c) to ensure this uniqueness.
-
-But we don't want to update the version numbers of VTIMEZONEs which have not
-changed. So we use the vzic-merge.pl Perl script. This merges in the new set
-of VTIMEZONEs with a 'master' set. It compares each new VTIMEZONE file with
-the one in the master set (ignoring changes to the TZID). If the new
-VTIMEZONE file is different, it copies it to the master set and sets the
-version number to the old VTIMEZONE's version number + 1.
-
-To use vzic-merge.pl you must change the $MASTER_ZONEINFO_DIR and
-$NEW_ZONEINFO_DIR variables at the top of the file to point to your 2 sets of
-VTIMEZONEs. You then just run the script. (I recommend you keep a backup of
-the old master VTIMEZONE files, and use diff to compare the new master set
-with the old one, in case anything goes wrong.)
-
-You must merge in changes to the zones.tab file by hand.
-
-Note that some timezones are renamed or removed occasionally, so applications
-should be able to cope with this.
-
-
-
-COMPATABILITY NOTES
-===================
-
-It seems that Microsoft Outlook is very picky about the iCalendar files it
-will accept. (I've been testing with Outlook 2000. I hope the other versions
-are no worse.) Here's a few problems we've had with the VTIMEZONEs:
-
- o Outlook doesn't like any years before 1600. We were using '1st Jan 0001'
- in all VTIMEZONEs to specify the first UTC offset known for the timezone.
- (The Olson data does not give a start date for this.)
-
- Now we just skip this first component for most timezones. The UTC offset
- can still be found from the TZOFFSETFROM property of the first component.
-
- Though some timezones only specify one UTC offset that applies forever,
- so in these cases we output '1st Jan 1970' (Indian/Cocos,
- Pacific/Johnston).
-
- o Outlook doesn't like the BYMONTHDAY specifier in RRULEs.
-
- We have changed most of the VTIMEZONEs to use things like 'BYDAY=2SU'
- rather than 'BYMONTHDAY=8,9,10,11,12,13,14;BYDAY=SU', though some of
- them were impossible to convert correctly so they are not always correct.
-
- o Outlook doesn't like TZOFFSETFROM/TZOFFSETTO properties which include a
- seconds component, e.g. 'TZOFFSETFROM:+110628'.
- Quite a lot of the Olson timezones include seconds in their UTC offsets,
- though no timezones currently have a UTC offset that uses the seconds
- value.
-
- We've rounded all UTC offsets to the nearest minute. Since all timezone
- offsets currently used have '00' as the seconds offset, this doesn't lose
- us much.
-
- o Outlook doesn't like lines being split in certain places, even though
- the iCalendar spec says they can be split anywhere.
-
- o Outlook can only handle one RDATE or a pair of RRULEs. So we had to remove
- all historical data.
-
-
-TESTING
-=======
-
-Do a 'make test-vic', then run ./test-vic.
-
-The test-vzic program compares our libical code and VTIMEZONE data against
-the Unix functions like mktime(). It steps over a period of time (1970-2037)
-converting from UTC to a given timezone and back again every 15 minutes.
-Any differences are output into the test-output directory.
-
-The output matches for all of the timezones, except in a few places where the
-result can't be determined. So I think we can be fairly confident that the
-VTIMEZONEs are correct.
-
-Note that you must use the same Olson data in libical that the OS is using
-for mktime() etc. For example, I am using RedHat 9 which uses tzdata2002d,
-so I converted this to VTIMEZONE files and installed it into the libical
-timezone data directory before testing. (You need to use '--pure' when
-creating the VTIMEZONE files as well.)
-
-
-Testing the Parsing Code
-------------------------
-
-Run 'make test-parse'.
-
-This runs 'vzic --dump' and 'perl-dump' and compares the output. The diff
-commands should not produce any output.
-
-'vzic --dump' dumps all the parsed data out in the original Olson format,
-but without comments. The files are written into the ZonesVzic and RulesVzic
-subdirectories of the zoneinfo directory.
-
-'make perl-dump' runs the vzic-dump.pl perl script which outputs the files
-in the same format as 'vzic --dump' in the ZonesPerl and RulesPerl
-subdirectories. The perl script doesn't actually parse the fields; it only
-strips comments and massages the fields so we have the same output format.
-
-Currently they both produce exactly the same output so we know the parsing
-code is OK.
-
-
-Testing the VTIMEZONE Files
----------------------------
-
-Run 'make test-changes'.
-
-This runs 'vzic --dump-changes' and 'test-vzic --dump-changes' and compares
-the output. The diff command should not produce any output.
-
-Both commands output timezone changes for each zone up to a specific year
-(2030) into files for each timezone. It outputs the timezone changes in a
-list in this format:
-
- Timezone Name Date and Time of Change in UTC New Offset from UTC
-
- America/Dawson 26 Oct 1986 2:00:00 -0800
-
-Unfortunately there are some differences here, but they all happen before
-1970 so it doesn't matter too much. It looks like the libical code has
-problems determining things like 'last Sunday of the month' before 1970.
-This is because it uses mktime() etc. which can't really handle dates
-before 1970.
-
-
-
-Damon Chaplin <damon@gnome.org>, 25 Oct 2003.
-
diff --git a/libkcal/libical/vzic-1.3/test-vzic.c b/libkcal/libical/vzic-1.3/test-vzic.c
deleted file mode 100644
index c06f27384..000000000
--- a/libkcal/libical/vzic-1.3/test-vzic.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/*
- * test-vzic.c - test vzic + libical against mktime() and friends.
- *
- * Note that when we output VCALENDAR data compatible with Outlook the
- * results aren't all correct.
- *
- * We have to modify some RRULEs which makes these timezones incorrect:
- *
- * Africa/Cairo
- * America/Godthab
- * America/Santiago
- * Antarctica/Palmer
- * Asia/Baghdad
- * Asia/Damascus
- * Asia/Jerusalem
- *
- * Also, we can only output one RDATE or a pair of RRULEs which may make some
- * other timezones incorrect sometimes (e.g. if they change).
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <ical.h>
-/*#include <evolution/ical.h>*/
-
-#define CHANGES_MAX_YEAR 2030
-
-/* These are the years between which we test against the Unix timezone
- functions, inclusive. When using 'vzic --pure' you can test the full
- range from 1970 to 2037 and it should match against mktime() etc.
- (assuming you are using the same Olson timezone data for both).
-
- But when using VTIMEZONE's that are compatible with Outlook, it is only
- worth testing times in the future. There will be lots of differences in
- the past, since we can't include any historical changes in the files. */
-#if 1
-#define DUMP_START_YEAR 2003
-#define DUMP_END_YEAR 2037
-#else
-#define DUMP_START_YEAR 1970
-#define DUMP_END_YEAR 2037
-#endif
-
-/* The maximum size of any complete pathname. */
-#define PATHNAME_BUFFER_SIZE 1024
-
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-#ifndef TRUE
-#define TRUE (!FALSE)
-#endif
-
-int VzicDumpChanges = FALSE;
-
-/* We output beneath the current directory for now. */
-char *directory = "test-output";
-
-static void usage (void);
-static int parse_zone_name (char *name,
- char **directory,
- char **subdirectory,
- char **filename);
-static void ensure_directory_exists (char *directory);
-static void dump_local_times (icaltimezone *zone,
- FILE *fp);
-
-
-int main(int argc, char* argv[])
-{
- icalarray *zones;
- icaltimezone *zone;
- char *zone_directory, *zone_subdirectory, *zone_filename, *location;
- char output_directory[PATHNAME_BUFFER_SIZE];
- char filename[PATHNAME_BUFFER_SIZE];
- FILE *fp;
- int i;
- int skipping = TRUE;
-
- /*
- * Command-Line Option Parsing.
- */
- for (i = 1; i < argc; i++) {
- /* --dump-changes: Dumps a list of times when each timezone changed,
- and the new local time offset from UTC. */
- if (!strcmp (argv[i], "--dump-changes"))
- VzicDumpChanges = TRUE;
-
- else
- usage ();
- }
-
-
- zones = icaltimezone_get_builtin_timezones ();
-
- ensure_directory_exists (directory);
-
- for (i = 0; i < zones->num_elements; i++) {
- zone = icalarray_element_at (zones, i);
-
- location = icaltimezone_get_location (zone);
-
-#if 0
- /* Use this to start at a certain zone. */
- if (skipping && strcmp (location, "America/Boise"))
- continue;
-#endif
-
- skipping = FALSE;
-
- /* Use this to only output data for certain timezones. */
-#if 0
- if (strcmp (location, "America/Cancun")
- && strcmp (location, "Asia/Baku")
- && strcmp (location, "Asia/Nicosia")
- && strcmp (location, "Asia/Novosibirsk")
- && strcmp (location, "Asia/Samarkand")
- && strcmp (location, "Asia/Tashkent")
- && strcmp (location, "Asia/Tbilisi")
- && strcmp (location, "Asia/Yerevan")
- && strcmp (location, "Australia/Broken_Hill")
- && strcmp (location, "Europe/Simferopol")
- && strcmp (location, "Europe/Tallinn")
- && strcmp (location, "Europe/Zaporozhye")
- )
- continue;
-#endif
-
-#if 0
- printf ("%s\n", location);
-#endif
-
- parse_zone_name (location, &zone_directory, &zone_subdirectory,
- &zone_filename);
-
- sprintf (output_directory, "%s/%s", directory, zone_directory);
- ensure_directory_exists (output_directory);
- sprintf (filename, "%s/%s", output_directory, zone_filename);
-
- if (zone_subdirectory) {
- sprintf (output_directory, "%s/%s/%s", directory, zone_directory,
- zone_subdirectory);
- ensure_directory_exists (output_directory);
- sprintf (filename, "%s/%s", output_directory, zone_filename);
- }
-
- fp = fopen (filename, "w");
- if (!fp) {
- fprintf (stderr, "Couldn't create file: %s\n", filename);
- exit (1);
- }
-
- /* We can run 2 different tests - output all changes for each zone, or
- test against mktime()/localtime(). Should have a command-line option
- or something. */
- if (VzicDumpChanges)
- icaltimezone_dump_changes (zone, CHANGES_MAX_YEAR, fp);
- else
- dump_local_times (zone, fp);
-
- if (ferror (fp)) {
- fprintf (stderr, "Error writing file: %s\n", filename);
- exit (1);
- }
-
- fclose (fp);
- }
-
- return 0;
-}
-
-
-static void
-usage (void)
-{
- fprintf (stderr, "Usage: test-vzic [--dump-changes]\n");
-
- exit (1);
-}
-
-
-/* This checks that the Zone name only uses the characters in [-+_/a-zA-Z0-9],
- and outputs a warning if it isn't. */
-static int
-parse_zone_name (char *name,
- char **directory,
- char **subdirectory,
- char **filename)
-{
- static int invalid_zone_num = 1;
-
- char *p, ch, *first_slash_pos = NULL, *second_slash_pos = NULL;
- int invalid = FALSE;
-
- for (p = name; (ch = *p) != 0; p++) {
- if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')
- && (ch < '0' || ch > '9') && ch != '/' && ch != '_'
- && ch != '-' && ch != '+') {
- fprintf (stderr, "Warning: Unusual Zone name: %s\n", name);
- invalid = TRUE;
- break;
- }
-
- if (ch == '/') {
- if (!first_slash_pos) {
- first_slash_pos = p;
- } else if (!second_slash_pos) {
- second_slash_pos = p;
- } else {
- fprintf (stderr, "Warning: More than 2 '/' characters in Zone name: %s\n", name);
- invalid = TRUE;
- break;
- }
- }
- }
-
- if (!first_slash_pos) {
- fprintf (stderr, "No '/' character in Zone name: %s. Skipping.\n", name);
- return FALSE;
- }
-
- if (invalid) {
- fprintf (stderr, "Invalid zone name: %s\n", name);
- exit (0);
- } else {
- *first_slash_pos = '\0';
- *directory = icalmemory_strdup (name);
- *first_slash_pos = '/';
-
- if (second_slash_pos) {
- *second_slash_pos = '\0';
- *subdirectory = icalmemory_strdup (first_slash_pos + 1);
- *second_slash_pos = '/';
-
- *filename = icalmemory_strdup (second_slash_pos + 1);
- } else {
- *subdirectory = NULL;
- *filename = icalmemory_strdup (first_slash_pos + 1);
- }
- }
-}
-
-
-static void
-ensure_directory_exists (char *directory)
-{
- struct stat filestat;
-
- if (stat (directory, &filestat) != 0) {
- /* If the directory doesn't exist, try to create it. */
- if (errno == ENOENT) {
- if (mkdir (directory, 0777) != 0) {
- fprintf (stderr, "Can't create directory: %s\n", directory);
- exit (1);
- }
- } else {
- fprintf (stderr, "Error calling stat() on directory: %s\n", directory);
- exit (1);
- }
- } else if (!S_ISDIR (filestat.st_mode)) {
- fprintf (stderr, "Can't create directory, already exists: %s\n",
- directory);
- exit (1);
- }
-}
-
-
-static void
-dump_local_times (icaltimezone *zone, FILE *fp)
-{
- static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- icaltimezone *utc_timezone;
- struct icaltimetype tt, tt_copy;
- struct tm tm, local_tm;
- time_t t;
- char tzstring[256], *location;
- int last_year_output = 0;
- int total_error = 0, total_error2 = 0;
-
- utc_timezone = icaltimezone_get_utc_timezone ();
-
- /* This is our UTC time that we will use to iterate over the period. */
- tt.year = DUMP_START_YEAR;
- tt.month = 1;
- tt.day = 1;
- tt.hour = 0;
- tt.minute = 0;
- tt.second = 0;
- tt.is_utc = 0;
- tt.is_date = 0;
- tt.zone = "";
-
- tm.tm_year = tt.year - 1900;
- tm.tm_mon = tt.month - 1;
- tm.tm_mday = tt.day;
- tm.tm_hour = tt.hour;
- tm.tm_min = tt.minute;
- tm.tm_sec = tt.second;
- tm.tm_isdst = -1;
-
- /* Convert it to a time_t by saying it is in UTC. */
- putenv ("TZ=UTC");
- t = mktime (&tm);
-
- location = icaltimezone_get_location (zone);
- sprintf (tzstring, "TZ=%s", location);
-
- /*printf ("Zone: %s\n", location);*/
- putenv (tzstring);
-
- /* Loop around converting the UTC time to local time, outputting it, and
- then adding on 15 minutes to the UTC time. */
- while (tt.year <= DUMP_END_YEAR) {
- if (tt.year > last_year_output) {
- last_year_output = tt.year;
-#if 0
- printf (" %i\n", last_year_output);
- fprintf (fp, " %i\n", last_year_output);
-#endif
- }
-
-#if 1
- /* First use the Unix functions. */
- /* Now convert it to a local time in the given timezone. */
- local_tm = *localtime (&t);
-#endif
-
-#if 1
- /* Now use libical. */
- tt_copy = tt;
- icaltimezone_convert_time (&tt_copy, utc_timezone, zone);
-#endif
-
-#if 1
- if (local_tm.tm_year + 1900 != tt_copy.year
- || local_tm.tm_mon + 1 != tt_copy.month
- || local_tm.tm_mday != tt_copy.day
- || local_tm.tm_hour != tt_copy.hour
- || local_tm.tm_min != tt_copy.minute
- || local_tm.tm_sec != tt_copy.second) {
-
- /* The error format is:
-
- ERROR: Original-UTC-Time Local-Time-From-mktime Local-Time-From-Libical
-
- */
-
- total_error++;
-
- fprintf (fp, "ERROR:%2i %s %04i %2i:%02i:%02i UTC",
- tt.day, months[tt.month - 1], tt.year,
- tt.hour, tt.minute, tt.second);
- fprintf (fp, " ->%2i %s %04i %2i:%02i:%02i",
- local_tm.tm_mday, months[local_tm.tm_mon],
- local_tm.tm_year + 1900,
- local_tm.tm_hour, local_tm.tm_min, local_tm.tm_sec);
- fprintf (fp, " Us:%2i %s %04i %2i:%02i:%02i\n",
- tt_copy.day, months[tt_copy.month - 1], tt_copy.year,
- tt_copy.hour, tt_copy.minute, tt_copy.second);
- }
-#endif
-
- /* Now convert it back, and check we get the original time. */
- icaltimezone_convert_time (&tt_copy, zone, utc_timezone);
- if (tt.year != tt_copy.year
- || tt.month != tt_copy.month
- || tt.day != tt_copy.day
- || tt.hour != tt_copy.hour
- || tt.minute != tt_copy.minute
- || tt.second != tt_copy.second) {
-
- total_error2++;
-
- fprintf (fp, "ERROR 2: %2i %s %04i %2i:%02i:%02i UTC",
- tt.day, months[tt.month - 1], tt.year,
- tt.hour, tt.minute, tt.second);
- fprintf (fp, " Us:%2i %s %04i %2i:%02i:%02i UTC\n",
- tt_copy.day, months[tt_copy.month - 1], tt_copy.year,
- tt_copy.hour, tt_copy.minute, tt_copy.second);
- }
-
-
- /* Increment the time. */
- icaltime_adjust (&tt, 0, 0, 15, 0);
-
- /* We assume leap seconds are not included in time_t values, which should
- be true on POSIX systems. */
- t += 15 * 60;
- }
-
- printf ("Zone: %40s Errors: %i (%i)\n", icaltimezone_get_location (zone),
- total_error, total_error2);
-}
diff --git a/libkcal/libical/vzic-1.3/vzic-dump.c b/libkcal/libical/vzic-1.3/vzic-dump.c
deleted file mode 100644
index 8e76aa80c..000000000
--- a/libkcal/libical/vzic-1.3/vzic-dump.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/*
- * These functions are for dumping all the parsed Zones and Rules to
- * files, to be compared with the output of vzic-dump.pl to check our parsing
- * code is OK. Some of the functions are also used for producing debugging
- * output.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vzic.h"
-#include "vzic-dump.h"
-
-
-static void dump_add_rule (char *name,
- GArray *rule_array,
- GPtrArray *name_array);
-static int dump_compare_strings (const void *arg1,
- const void *arg2);
-
-
-void
-dump_zone_data (GArray *zone_data,
- char *filename)
-{
- static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- FILE *fp;
- ZoneData *zone;
- ZoneLineData *zone_line;
- int i, j;
- gboolean output_month, output_day, output_time;
-
- fp = fopen (filename, "w");
- if (!fp) {
- fprintf (stderr, "Couldn't create file: %s\n", filename);
- exit (1);
- }
-
- for (i = 0; i < zone_data->len; i++) {
- zone = &g_array_index (zone_data, ZoneData, i);
-
- fprintf (fp, "Zone\t%s\t", zone->zone_name);
-
- for (j = 0; j < zone->zone_line_data->len; j++) {
- zone_line = &g_array_index (zone->zone_line_data, ZoneLineData, j);
-
- if (j != 0)
- fprintf (fp, "\t\t\t");
-
- fprintf (fp, "%s\t", dump_time (zone_line->stdoff_seconds, TIME_WALL,
- FALSE));
-
- if (zone_line->rules)
- fprintf (fp, "%s\t", zone_line->rules);
- else if (zone_line->save_seconds != 0)
- fprintf (fp, "%s\t", dump_time (zone_line->save_seconds, TIME_WALL,
- FALSE));
- else
- fprintf (fp, "-\t");
-
- fprintf (fp, "%s\t", zone_line->format ? zone_line->format : "-");
-
- if (zone_line->until_set) {
- fprintf (fp, "%s\t", dump_year (zone_line->until_year));
-
- output_month = output_day = output_time = FALSE;
-
- if (zone_line->until_time_code != TIME_WALL
- || zone_line->until_time_seconds != 0)
- output_month = output_day = output_time = TRUE;
- else if (zone_line->until_day_code != DAY_SIMPLE
- || zone_line->until_day_number != 1)
- output_month = output_day = TRUE;
- else if (zone_line->until_month != 0)
- output_month = TRUE;
-
- if (output_month)
- fprintf (fp, "%s", months[zone_line->until_month]);
-
- fprintf (fp, "\t");
-
- if (output_day)
- fprintf (fp, "%s", dump_day_coded (zone_line->until_day_code,
- zone_line->until_day_number,
- zone_line->until_day_weekday));
-
- fprintf (fp, "\t");
-
- if (output_time)
- fprintf (fp, "%s", dump_time (zone_line->until_time_seconds,
- zone_line->until_time_code, FALSE));
-
- } else {
- fprintf (fp, "\t\t\t");
- }
-
- fprintf (fp, "\n");
- }
- }
-
- fclose (fp);
-}
-
-
-void
-dump_rule_data (GHashTable *rule_data,
- char *filename)
-{
- FILE *fp;
- GPtrArray *name_array;
- GArray *rule_array;
- int i;
- char *name;
-
- fp = fopen (filename, "w");
- if (!fp) {
- fprintf (stderr, "Couldn't create file: %s\n", filename);
- exit (1);
- }
-
- /* We need to sort the rules by their names, so they are in the same order
- as the Perl output. So we place all the names in a temporary GPtrArray,
- sort it, then output them. */
- name_array = g_ptr_array_new ();
- g_hash_table_foreach (rule_data, (GHFunc) dump_add_rule, name_array);
- qsort (name_array->pdata, name_array->len, sizeof (char*),
- dump_compare_strings);
-
- for (i = 0; i < name_array->len; i++) {
- name = g_ptr_array_index (name_array, i);
- rule_array = g_hash_table_lookup (rule_data, name);
- if (!rule_array) {
- fprintf (stderr, "Couldn't access rules: %s\n", name);
- exit (1);
- }
- dump_rule_array (name, rule_array, fp);
- }
-
- g_ptr_array_free (name_array, TRUE);
-
- fclose (fp);
-}
-
-
-static void
-dump_add_rule (char *name,
- GArray *rule_array,
- GPtrArray *name_array)
-{
- g_ptr_array_add (name_array, name);
-}
-
-
-static int
-dump_compare_strings (const void *arg1,
- const void *arg2)
-{
- char **a, **b;
-
- a = (char**) arg1;
- b = (char**) arg2;
-
- return strcmp (*a, *b);
-}
-
-
-void
-dump_rule_array (char *name,
- GArray *rule_array,
- FILE *fp)
-{
- static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- RuleData *rule;
- int i;
-
-#if 0
- fprintf (fp, "\n# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S");
-#endif
-
- for (i = 0; i < rule_array->len; i++) {
- rule = &g_array_index (rule_array, RuleData, i);
-
- fprintf (fp, "Rule\t%s\t%s\t", name, dump_year (rule->from_year));
-
- if (rule->to_year == rule->from_year)
- fprintf (fp, "only\t");
- else
- fprintf (fp, "%s\t", dump_year (rule->to_year));
-
- fprintf (fp, "%s\t", rule->type ? rule->type : "-");
-
- fprintf (fp, "%s\t", months[rule->in_month]);
-
- fprintf (fp, "%s\t",
- dump_day_coded (rule->on_day_code, rule->on_day_number,
- rule->on_day_weekday));
-
- fprintf (fp, "%s\t", dump_time (rule->at_time_seconds, rule->at_time_code,
- FALSE));
-
- fprintf (fp, "%s\t", dump_time (rule->save_seconds, TIME_WALL, TRUE));
-
- fprintf (fp, "%s", rule->letter_s ? rule->letter_s : "-");
-
- fprintf (fp, "\n");
- }
-}
-
-
-char*
-dump_time (int seconds,
- TimeCode time_code,
- gboolean use_zero)
-{
- static char buffer[256], *sign;
- int hours, minutes;
- char *code;
-
- if (time_code == TIME_STANDARD)
- code = "s";
- else if (time_code == TIME_UNIVERSAL)
- code = "u";
- else
- code = "";
-
- if (seconds < 0) {
- seconds = -seconds;
- sign = "-";
- } else {
- sign = "";
- }
-
- hours = seconds / 3600;
- minutes = (seconds % 3600) / 60;
- seconds = seconds % 60;
-
- if (use_zero && hours == 0 && minutes == 0 && seconds == 0)
- return "0";
- else if (seconds == 0)
- sprintf (buffer, "%s%i:%02i%s", sign, hours, minutes, code);
- else
- sprintf (buffer, "%s%i:%02i:%02i%s", sign, hours, minutes, seconds, code);
-
- return buffer;
-}
-
-
-char*
-dump_day_coded (DayCode day_code,
- int day_number,
- int day_weekday)
-{
- static char buffer[256];
- static char *weekdays[] = { "Sun", "Mon", "Tue", "Wed",
- "Thu", "Fri", "Sat" };
-
- switch (day_code) {
- case DAY_SIMPLE:
- sprintf (buffer, "%i", day_number);
- break;
- case DAY_WEEKDAY_ON_OR_AFTER:
- sprintf (buffer, "%s>=%i", weekdays[day_weekday], day_number);
- break;
- case DAY_WEEKDAY_ON_OR_BEFORE:
- sprintf (buffer, "%s<=%i", weekdays[day_weekday], day_number);
- break;
- case DAY_LAST_WEEKDAY:
- sprintf (buffer, "last%s", weekdays[day_weekday]);
- break;
- default:
- fprintf (stderr, "Invalid day code: %i\n", day_code);
- exit (1);
- }
-
- return buffer;
-}
-
-
-char*
-dump_year (int year)
-{
- static char buffer[256];
-
- if (year == YEAR_MINIMUM)
- return "min";
- if (year == YEAR_MAXIMUM)
- return "max";
-
- sprintf (buffer, "%i", year);
- return buffer;
-}
-
-
-void
-dump_time_zone_names (GList *names,
- char *output_dir,
- GHashTable *zones_hash)
-{
- char filename[PATHNAME_BUFFER_SIZE], *zone_name, *zone_name_in_hash = NULL;
- char strings_filename[PATHNAME_BUFFER_SIZE];
- FILE *fp, *strings_fp = NULL;
- GList *elem;
- ZoneDescription *zone_desc;
-
- sprintf (filename, "%s/zones.tab", output_dir);
- sprintf (strings_filename, "%s/zones.h", output_dir);
-
- fp = fopen (filename, "w");
- if (!fp) {
- fprintf (stderr, "Couldn't create file: %s\n", filename);
- exit (1);
- }
-
- if (VzicDumpZoneTranslatableStrings) {
- strings_fp = fopen (strings_filename, "w");
- if (!strings_fp) {
- fprintf (stderr, "Couldn't create file: %s\n", strings_filename);
- exit (1);
- }
- }
-
- names = g_list_sort (names, (GCompareFunc) strcmp);
-
- elem = names;
- while (elem) {
- zone_name = (char*) elem->data;
-
- zone_desc = g_hash_table_lookup (zones_hash, zone_name);
-
- /* SPECIAL CASES: These timezones are links from other zones and are
- almost exactly the same - they are basically there so users can find
- them a bit easier. But they don't have entries in the zone.tab file,
- so we use the entry from the timezone linked from. */
- if (!zone_desc) {
- if (!strcmp (zone_name, "America/Indiana/Indianapolis"))
- zone_name_in_hash = "America/Indianapolis";
- else if (!strcmp (zone_name, "America/Kentucky/Louisville"))
- zone_name_in_hash = "America/Louisville";
- else if (!strcmp (zone_name, "Asia/Istanbul"))
- zone_name_in_hash = "Europe/Istanbul";
- else if (!strcmp (zone_name, "Europe/Nicosia"))
- zone_name_in_hash = "Asia/Nicosia";
-
- if (zone_name_in_hash)
- zone_desc = g_hash_table_lookup (zones_hash, zone_name_in_hash);
- }
-
- if (zone_desc) {
- fprintf (fp, "%+04i%02i%02i %+04i%02i%02i %s\n",
- zone_desc->latitude[0], zone_desc->latitude[1],
- zone_desc->latitude[2],
- zone_desc->longitude[0], zone_desc->longitude[1],
- zone_desc->longitude[2],
- zone_name);
- } else {
- g_print ("Zone description not found for: %s\n", zone_name);
- fprintf (fp, "%s\n", zone_name);
- }
-
-
- if (VzicDumpZoneTranslatableStrings) {
-#if 0
- char zone_name_buffer[1024], *src, *dest;
-
- for (src = zone_name, dest = zone_name_buffer; *src; src++, dest++)
- *dest = (*src == '_') ? ' ' : *src;
- *dest = '\0';
-#endif
-
- fprintf (strings_fp, "N_(\"%s\");\n", zone_name);
- }
-
- elem = elem->next;
- }
-
- fclose (fp);
-
- if (VzicDumpZoneTranslatableStrings)
- fclose (strings_fp);
-}
-
diff --git a/libkcal/libical/vzic-1.3/vzic-dump.h b/libkcal/libical/vzic-1.3/vzic-dump.h
deleted file mode 100644
index b37741a1e..000000000
--- a/libkcal/libical/vzic-1.3/vzic-dump.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/*
- * These functions are for dumping all the parsed Zones and Rules to
- * files, to be compared with the output of vzic-dump.pl to check our parsing
- * code is OK. Some of the functions are also used for producing debugging
- * output.
- */
-
-#ifndef _VZIC_DUMP_H_
-#define _VZIC_DUMP_H_
-
-#include <glib.h>
-
-void dump_zone_data (GArray *zone_data,
- char *filename);
-void dump_rule_data (GHashTable *rule_data,
- char *filename);
-
-void dump_rule_array (char *name,
- GArray *rule_array,
- FILE *fp);
-
-char* dump_year (int year);
-char* dump_day_coded (DayCode day_code,
- int day_number,
- int day_weekday);
-char* dump_time (int seconds,
- TimeCode time_code,
- gboolean use_zero);
-
-void dump_time_zone_names (GList *names,
- char *output_dir,
- GHashTable *zones_hash);
-
-#endif /* _VZIC_DUMP_H_ */
diff --git a/libkcal/libical/vzic-1.3/vzic-dump.pl b/libkcal/libical/vzic-1.3/vzic-dump.pl
deleted file mode 100755
index e73185cae..000000000
--- a/libkcal/libical/vzic-1.3/vzic-dump.pl
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/usr/bin/perl -w
-
-#
-# Vzic - a program to convert Olson timezone database files into VZTIMEZONE
-# files compatible with the iCalendar specification (RFC2445).
-#
-# Copyright (C) 2000-2001 Ximian, Inc.
-# Copyright (C) 2003 Damon Chaplin.
-#
-# Author: Damon Chaplin <damon@gnome.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-#
-# This reads the Olson timezone files, strips any comments, and outputs them
-# in a very simple format with tab-separated fields. It is used to compare
-# with the output of dump_zone_data() and dump_rule_data() to double-check
-# that we have parsed the files correctly.
-#
-
-my $zones_fh = "zonesfile";
-my $rules_fh = "rulesfile";
-
-my %Rules;
-
-if ($#ARGV != 0) {
- die "Usage: $0 <OlsonDirectory>";
-}
-
-my $OLSON_DIR = $ARGV[0];
-
-# We place output in subdirectories of the current directory.
-my $OUTPUT_DIR = "zoneinfo";
-
-if (! -d "$OUTPUT_DIR") {
- mkdir ("$OUTPUT_DIR", 0777)
- || die "Can't create directory: $OUTPUT_DIR";
-}
-if (! -d "$OUTPUT_DIR/ZonesPerl") {
- mkdir ("$OUTPUT_DIR/ZonesPerl", 0777)
- || die "Can't create directory: $OUTPUT_DIR/ZonesPerl";
-}
-if (! -d "$OUTPUT_DIR/RulesPerl") {
- mkdir ("$OUTPUT_DIR/RulesPerl", 0777)
- || die "Can't create directory: $OUTPUT_DIR/RulesPerl";
-}
-
-
-&ReadOlsonFile ("africa");
-&ReadOlsonFile ("antarctica");
-&ReadOlsonFile ("asia");
-&ReadOlsonFile ("australasia");
-&ReadOlsonFile ("europe");
-&ReadOlsonFile ("northamerica");
-&ReadOlsonFile ("southamerica");
-
-# These are backwards-compatability and weird stuff.
-#&ReadOlsonFile ("backward");
-#&ReadOlsonFile ("etcetera");
-#&ReadOlsonFile ("leapseconds");
-#&ReadOlsonFile ("pacificnew");
-#&ReadOlsonFile ("solar87");
-#&ReadOlsonFile ("solar88");
-#&ReadOlsonFile ("solar89");
-
-# We don't do this one since it is not useful and the use of '"' in the Zone
-# line messes up our split() command.
-#&ReadOlsonFile ("factory");
-
-# We don't do this since the vzic program can't do it.
-#&ReadOlsonFile ("systemv");
-
-
-
-
-1;
-
-
-sub ReadOlsonFile {
- my ($file) = @_;
-
-# print ("Reading olson file: $file\n");
-
- open (OLSONFILE, "$OLSON_DIR/$file")
- || die "Can't open file: $file";
-
- open ($zones_fh, ">$OUTPUT_DIR/ZonesPerl/$file")
- || die "Can't open file: $OUTPUT_DIR/ZonesPerl/$file";
-
- open ($rules_fh, ">$OUTPUT_DIR/RulesPerl/$file")
- || die "Can't open file: $OUTPUT_DIR/RulesPerl/$file";
-
- %Rules = ();
-
- my $zone_continues = 0;
-
- while (<OLSONFILE>) {
- next if (m/^#/);
-
- # '#' characters can appear in strings, but the Olson files don't use
- # that feature at present so we treat all '#' as comments for now.
- s/#.*//;
-
- next if (m/^\s*$/);
-
- if ($zone_continues) {
- $zone_continues = &ReadZoneContinuationLine;
-
- } elsif (m/^Rule\s/) {
- &ReadRuleLine;
-
- } elsif (m/^Zone\s/) {
- $zone_continues = &ReadZoneLine;
-
- } elsif (m/^Link\s/) {
-# print "Link: $link_from, $link_to\n";
-
- } elsif (m/^Leap\s/) {
-# print "Leap\n";
-
- } else {
- die "Invalid line: $_";
- }
- }
-
-# print ("Read olson file: $file\n");
-
- foreach $key (sort (keys (%Rules))) {
- print $rules_fh "$Rules{$key}"
- }
-
- close ($zones_fh);
- close ($rules_fh);
- close (OLSONFILE);
-}
-
-
-sub ReadZoneLine {
- my ($zone, $name, $gmtoff, $rules_save, $format,
- $until_year, $until_month, $until_day, $until_time, $remainder)
- = split ' ', $_, 10;
-
- return &ReadZoneLineCommon ($zone, $name, $gmtoff, $rules_save, $format,
- $until_year, $until_month, $until_day,
- $until_time);
-}
-
-
-sub ReadZoneContinuationLine {
- my ($gmtoff, $rules_save, $format,
- $until_year, $until_month, $until_day, $until_time, $remainder)
- = split ' ', $_, 8;
-
- return &ReadZoneLineCommon ("", "", $gmtoff, $rules_save, $format,
- $until_year, $until_month, $until_day,
- $until_time);
-}
-
-
-sub ReadZoneLineCommon {
- my ($zone, $name, $gmtoff, $rules_save, $format,
- $until_year, $until_month, $until_day, $until_time) = @_;
-
- if (!defined ($until_year)) { $until_year = ""; }
- if (!defined ($until_month)) { $until_month = ""; }
- if (!defined ($until_day)) { $until_day = ""; }
- if (!defined ($until_time)) { $until_time = ""; }
-
- # A few of the gmtoffsets have an unnecessary :00 seconds.
- $gmtoff =~ s/(\d+):(\d+):00/$1:$2/;
-
- # Make sure the gmtoff does have minutes.
- $gmtoff =~ s/^(-?\d+)$/$1:00/;
-
- # Fix a few other bits so they all use the same format.
- if ($gmtoff eq "0") { $gmtoff = "0:00"; }
- $until_time =~ s/^0(\d):/$1:/;
- if ($until_time eq "0:00") { $until_time = ""; }
- if ($until_day eq "1" && $until_time eq "") { $until_day = ""; }
- if ($until_month eq "Jan" && $until_day eq "" && $until_time eq "") {
- $until_month = "";
- }
-
- # For Zone continuation lines we need to insert an extra TAB.
- if (!$zone) { $zone = "\t" };
-
- print $zones_fh "$zone\t$name\t$gmtoff\t$rules_save\t$format\t$until_year\t$until_month\t$until_day\t$until_time\n";
-
- if (defined ($until_year) && $until_year) {
- return 1;
- } else {
- return 0;
- }
-}
-
-
-sub ReadRuleLine {
- my ($rule, $name, $from, $to, $type, $in, $on, $at, $save, $letter_s,
- $remainder) = split;
-
- $at =~ s/(\d+:\d+):00/$1/;
- $save =~ s/(\d+:\d+):00/$1/;
- if ($save eq "0:00") { $save = "0"; }
-
- $Rules{$name} .= "$rule\t$name\t$from\t$to\t$type\t$in\t$on\t$at\t$save\t$letter_s\n";
-
-# print $rules_fh "$rule\t$name\t$from\t$to\t$type\t$in\t$on\t$at\t$save\t$letter_s\n";
-}
-
diff --git a/libkcal/libical/vzic-1.3/vzic-merge.pl b/libkcal/libical/vzic-1.3/vzic-merge.pl
deleted file mode 100755
index 020f57089..000000000
--- a/libkcal/libical/vzic-1.3/vzic-merge.pl
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/perl -w
-
-#
-# Vzic - a program to convert Olson timezone database files into VZTIMEZONE
-# files compatible with the iCalendar specification (RFC2445).
-#
-# Copyright (C) 2001 Ximian, Inc.
-# Copyright (C) 2003 Damon Chaplin.
-#
-# Author: Damon Chaplin <damon@gnome.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-#
-# This merges in a new set of VTIMEZONE files with the 'master' set. It only
-# updates the files in the master set if the VTIMEZONE component has really
-# been changes. Note that the TZID normally includes the date the VTIMEZONE
-# file was generated on, so we have to ignore this when comparing the files.
-#
-
-# Set these to the toplevel directories of the 2 sets of VTIMEZONE files.
-#$MASTER_ZONEINFO_DIR = "/home/damon/cvs/libical/zoneinfo";
-$MASTER_ZONEINFO_DIR = "/usr/share/libical-evolution/zoneinfo";
-$NEW_ZONEINFO_DIR = "/home/damon/src/vzic-1.0/zoneinfo";
-
-# Set this to 1 if you have version numbers in the TZID like libical.
-$LIBICAL_VERSIONING = 1;
-
-# Set this to 0 for dry-runs, and 1 to actually update.
-$DO_UPDATES = 1;
-
-# Save this so we can restore it later.
-$input_record_separator = $/;
-
-chdir $NEW_ZONEINFO_DIR
- || die "Can't cd to $NEW_ZONEINFO_DIR";
-
-foreach $new_file (`find -name "*.ics"`) {
- # Get rid of './' at start and whitespace at end.
- $new_file =~ s/^\.\///;
- $new_file =~ s/\s+$//;
-
-# print "File: $new_file\n";
-
- open (NEWZONEFILE, "$new_file")
- || die "Can't open file: $NEW_ZONEINFO_DIR/$new_file";
- undef $/;
- $new_contents = <NEWZONEFILE>;
- $/ = $input_record_separator;
- close (NEWZONEFILE);
-
- $master_file = $MASTER_ZONEINFO_DIR . "/$new_file";
-
-# print "Master File: $master_file\n";
-
- $copy_to_master = 0;
-
- # If the ics file exists in the master copy we have to compare them,
- # otherwise we can just copy the new file into the master directory.
- if (-e $master_file) {
- open (MASTERZONEFILE, "$master_file")
- || die "Can't open file: $master_file";
- undef $/;
- $master_contents = <MASTERZONEFILE>;
- $/ = $input_record_separator;
- close (MASTERZONEFILE);
-
- $new_contents_copy = $new_contents;
-
- # Strip the TZID from both contents.
- $new_contents_copy =~ s/^TZID:\S+$//m;
- $new_tzid = $&;
- $master_contents =~ s/^TZID:\S+$//m;
- $master_tzid = $&;
-
-# print "Matched: $master_tzid\n";
-
-
- if ($new_contents_copy ne $master_contents) {
- print "$new_file has changed. Updating...\n";
- $copy_to_master = 1;
-
- if ($LIBICAL_VERSIONING) {
- # We bump the version number in the new file.
- $master_tzid =~ m%_(\d+)/%;
- $version_num = $1;
-# print "Version: $version_num\n";
-
- $version_num++;
- $new_tzid =~ s%_(\d+)/%_$version_num/%;
-
-# print "New TZID: $new_tzid\n";
- $new_contents =~ s/^TZID:\S+$/$new_tzid/m;
- }
- }
-
- } else {
- print "$new_file doesn't exist in master directory. Copying...\n";
- $copy_to_master = 1;
- }
-
- if ($copy_to_master) {
-# print "Updating: $new_file\n";
-
- if ($DO_UPDATES) {
- open (MASTERZONEFILE, ">$master_file")
- || die "Can't create file: $master_file";
- print MASTERZONEFILE $new_contents;
- close (MASTERZONEFILE);
- }
- }
-
-}
-
diff --git a/libkcal/libical/vzic-1.3/vzic-output.c b/libkcal/libical/vzic-1.3/vzic-output.c
deleted file mode 100644
index 87dd7529c..000000000
--- a/libkcal/libical/vzic-1.3/vzic-output.c
+++ /dev/null
@@ -1,2325 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/* ALGORITHM:
- *
- * First we expand all the Rule arrays, so that each element only represents 1
- * year. If a Rule extends to infinity we expand it up to a few years past the
- * maximum UNTIL year used in any of the timezones. We do this to make sure
- * that the last of the expanded Rules (which may be infinite) is only used
- * in the last of the time periods (i.e. the last Zone line).
- *
- * The Rule arrays are also sorted by the start time (FROM + IN + ON + AT).
- * Doing all this makes it much easier to find which rules apply to which
- * periods.
- *
- * For each timezone (i.e. ZoneData element), we step through each of the
- * time periods, the ZoneLineData elements (which represent each Zone line
- * from the Olson file.)
- *
- * We calculate the start & end time of the period.
- * - For the first line the start time is -infinity.
- * - For the last line the end time is +infinity.
- * - The end time of each line is also the start time of the next.
- *
- * We create an array of time changes which occur in this period, including
- * the one implied by the Zone line itself (though this is later taken out
- * if it is found to be at exactly the same time as the first Rule).
- *
- * Now we iterate over the time changes, outputting them as STANDARD or
- * DAYLIGHT components. We also try to merge them together into RRULEs or
- * use RDATEs.
- */
-
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "vzic.h"
-#include "vzic-output.h"
-
-#include "vzic-dump.h"
-
-
-/* These come from the Makefile. See the comments there. */
-char *ProductID = PRODUCT_ID;
-char *TZIDPrefix = TZID_PREFIX;
-
-/* We expand the TZIDPrefix, replacing %D with the date, in here. */
-char TZIDPrefixExpanded[1024];
-
-
-/* We only use RRULEs if there are at least MIN_RRULE_OCCURRENCES occurrences,
- since otherwise RDATEs are more efficient. Actually, I've set this high
- so we only use RRULEs for infinite recurrences. Since expanding RRULEs is
- very time-consuming, this seems sensible. */
-#define MIN_RRULE_OCCURRENCES 100
-
-
-/* The year we go up to when dumping the list of timezone changes (used
- for testing & debugging). */
-#define MAX_CHANGES_YEAR 2030
-
-/* This is the maximum year that time_t value can typically hold on 32-bit
- systems. */
-#define MAX_TIME_T_YEAR 2037
-
-
-/* The year we use to start RRULEs. */
-#define RRULE_START_YEAR 1970
-
-/* The year we use for RDATEs. */
-#define RDATE_YEAR 1970
-
-
-static char *WeekDays[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
-static int DaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-char *CurrentZoneName;
-
-
-typedef struct _VzicTime VzicTime;
-struct _VzicTime
-{
- /* Normal years, e.g. 2001. */
- int year;
-
- /* 0 (Jan) to 11 (Dec). */
- int month;
-
- /* The day, either a simple month day number, 1-31, or a rule such as
- the last Sunday, or the first Monday on or after the 8th. */
- DayCode day_code;
- int day_number; /* 1 to 31. */
- int day_weekday; /* 0 (Sun) to 6 (Sat). */
-
- /* The time, in seconds from midnight. The code specifies whether the
- time is a wall clock time, local standard time, or universal time. */
- int time_seconds;
- TimeCode time_code;
-
- /* The offset from UTC for local standard time. */
- int stdoff;
-
- /* The offset from UTC for local wall clock time. If this is different to
- stdoff then this is a DAYLIGHT component. This is TZOFFSETTO. */
- int walloff;
-
- /* TRUE if the time change recurs every year to infinity. */
- gboolean is_infinite;
-
- /* TRUE if the change has already been output. */
- gboolean output;
-
- /* These are the offsets of the previous VzicTime, and are used when
- calculating the time of the change. We place them here in
- output_zone_components() to simplify the output code. */
- int prev_stdoff;
- int prev_walloff;
-
- /* The abbreviated form of the timezone name. Note that this may not be
- unique. */
- char *tzname;
-};
-
-
-static void expand_and_sort_rule_array (gpointer key,
- gpointer value,
- gpointer data);
-static int rule_sort_func (const void *arg1,
- const void *arg2);
-static void output_zone (char *directory,
- ZoneData *zone,
- char *zone_name,
- GHashTable *rule_data);
-static gboolean parse_zone_name (char *name,
- char **directory,
- char **subdirectory,
- char **filename);
-static void output_zone_to_files (ZoneData *zone,
- char *zone_name,
- GHashTable *rule_data,
- FILE *fp,
- FILE *changes_fp);
-static gboolean add_rule_changes (ZoneLineData *zone_line,
- char *zone_name,
- GArray *changes,
- GHashTable *rule_data,
- VzicTime *start,
- VzicTime *end,
- char **start_letter_s,
- int *save_seconds);
-static char* expand_tzname (char *zone_name,
- char *format,
- gboolean have_letter_s,
- char *letter_s,
- gboolean is_daylight);
-static int compare_times (VzicTime *time1,
- int stdoff1,
- int walloff1,
- VzicTime *time2,
- int stdoff2,
- int walloff2);
-static gboolean times_match (VzicTime *time1,
- int stdoff1,
- int walloff1,
- VzicTime *time2,
- int stdoff2,
- int walloff2);
-static void output_zone_components (FILE *fp,
- char *name,
- GArray *changes);
-static void set_previous_offsets (GArray *changes);
-static gboolean check_for_recurrence (FILE *fp,
- GArray *changes,
- int idx);
-static void check_for_rdates (FILE *fp,
- GArray *changes,
- int idx);
-static gboolean timezones_match (char *tzname1,
- char *tzname2);
-static int output_component_start (char *buffer,
- VzicTime *vzictime,
- gboolean output_rdate,
- gboolean use_same_tz_offset);
-static void output_component_end (FILE *fp,
- VzicTime *vzictime);
-
-static void vzictime_init (VzicTime *vzictime);
-static int calculate_actual_time (VzicTime *vzictime,
- TimeCode time_code,
- int stdoff,
- int walloff);
-static int calculate_wall_time (int time,
- TimeCode time_code,
- int stdoff,
- int walloff,
- int *day_offset);
-static int calculate_until_time (int time,
- TimeCode time_code,
- int stdoff,
- int walloff,
- int *year,
- int *month,
- int *day);
-static void fix_time_overflow (int *year,
- int *month,
- int *day,
- int day_offset);
-
-static char* format_time (int year,
- int month,
- int day,
- int time);
-static char* format_tz_offset (int tz_offset,
- gboolean round_seconds);
-static gboolean output_rrule (char *rrule_buffer,
- int month,
- DayCode day_code,
- int day_number,
- int day_weekday,
- int day_offset,
- char *until);
-static gboolean output_rrule_2 (char *buffer,
- int month,
- int day_number,
- int day_weekday);
-
-static char* format_vzictime (VzicTime *vzictime);
-
-static void dump_changes (FILE *fp,
- char *zone_name,
- GArray *changes);
-static void dump_change (FILE *fp,
- char *zone_name,
- VzicTime *vzictime,
- int year);
-
-static void expand_tzid_prefix (void);
-
-
-void
-output_vtimezone_files (char *directory,
- GArray *zone_data,
- GHashTable *rule_data,
- GHashTable *link_data,
- int max_until_year)
-{
- ZoneData *zone;
- GList *links;
- char *link_to;
- int i;
-
- /* Insert today's date into the TZIDs we output. */
- expand_tzid_prefix ();
-
- /* Expand the rule data so that each entry specifies only one year, and
- sort it so we can easily find the rules applicable to each Zone span. */
- g_hash_table_foreach (rule_data, expand_and_sort_rule_array,
- GINT_TO_POINTER (max_until_year));
-
- /* Output each timezone. */
- for (i = 0; i < zone_data->len; i++) {
- zone = &g_array_index (zone_data, ZoneData, i);
- output_zone (directory, zone, zone->zone_name, rule_data);
-
- /* Look for any links from this zone. */
- links = g_hash_table_lookup (link_data, zone->zone_name);
-
- while (links) {
- link_to = links->data;
-
- /* We ignore Links that don't have a '/' in them (things like 'EST5EDT').
- */
- if (strchr (link_to, '/')) {
- output_zone (directory, zone, link_to, rule_data);
- }
-
- links = links->next;
- }
- }
-}
-
-
-static void
-expand_and_sort_rule_array (gpointer key,
- gpointer value,
- gpointer data)
-{
- char *name = key;
- GArray *rule_array = value;
- RuleData *rule, tmp_rule;
- int len, max_year, i, from, to, year;
- gboolean is_infinite;
-
- /* We expand the rule data to a year greater than any year used in a Zone
- UNTIL value. This is so that we can easily get parts of the array to
- use for each Zone line. */
- max_year = GPOINTER_TO_INT (data) + 2;
-
- /* If any of the rules apply to several years, we turn it into a single rule
- for each year. If the Rule is infinite we go up to max_year.
- We change the FROM field in the copies of the Rule, setting it to each
- of the years, and set TO to FROM, except if TO was YEAR_MAXIMUM we set
- the last TO to YEAR_MAXIMUM, so we still know the Rule is infinite. */
- len = rule_array->len;
- for (i = 0; i < len; i++) {
- rule = &g_array_index (rule_array, RuleData, i);
-
- /* None of the Rules currently use the TYPE field, but we'd better check.
- */
- if (rule->type) {
- fprintf (stderr, "Rules %s has a TYPE: %s\n", name, rule->type);
- exit (1);
- }
-
- if (rule->from_year != rule->to_year) {
- from = rule->from_year;
- to = rule->to_year;
-
- tmp_rule = *rule;
-
- /* Flag that this is a shallow copy so we don't free anything twice. */
- tmp_rule.is_shallow_copy = TRUE;
-
- /* See if it is an infinite Rule. */
- if (to == YEAR_MAXIMUM) {
- is_infinite = TRUE;
- to = max_year;
- if (from < to)
- rule->to_year = rule->from_year;
- } else {
- is_infinite = FALSE;
- }
-
- /* Create a copy of the Rule for each year. */
- for (year = from + 1; year <= to; year++) {
- tmp_rule.from_year = year;
-
- /* If the Rule is infinite, mark the last copy as infinite. */
- if (year == to && is_infinite)
- tmp_rule.to_year = YEAR_MAXIMUM;
- else
- tmp_rule.to_year = year;
-
- g_array_append_val (rule_array, tmp_rule);
- }
- }
- }
-
- /* Now sort the rules. */
- qsort (rule_array->data, rule_array->len, sizeof (RuleData), rule_sort_func);
-
-#if 0
- dump_rule_array (name, rule_array, stdout);
-#endif
-}
-
-
-/* This is used to sort the rules, after the rules have all been expanded so
- that each one is only for one year. */
-static int
-rule_sort_func (const void *arg1,
- const void *arg2)
-{
- RuleData *rule1, *rule2;
- int time1_year, time1_month, time1_day;
- int time2_year, time2_month, time2_day;
- int month_diff, result;
- VzicTime t1, t2;
-
- rule1 = (RuleData*) arg1;
- rule2 = (RuleData*) arg2;
-
- time1_year = rule1->from_year;
- time1_month = rule1->in_month;
- time2_year = rule2->from_year;
- time2_month = rule2->in_month;
-
- /* If there is more that one month difference we don't need to calculate
- the day or time. */
- month_diff = (time1_year - time2_year) * 12 + time1_month - time2_month;
-
- if (month_diff > 1)
- return 1;
- if (month_diff < -1)
- return -1;
-
- /* Now we have to calculate the day and time of the Rule start and the
- VzicTime, using the given offsets. */
- t1.year = time1_year;
- t1.month = time1_month;
- t1.day_code = rule1->on_day_code;
- t1.day_number = rule1->on_day_number;
- t1.day_weekday = rule1->on_day_weekday;
- t1.time_code = rule1->at_time_code;
- t1.time_seconds = rule1->at_time_seconds;
-
- t2.year = time2_year;
- t2.month = time2_month;
- t2.day_code = rule2->on_day_code;
- t2.day_number = rule2->on_day_number;
- t2.day_weekday = rule2->on_day_weekday;
- t2.time_code = rule2->at_time_code;
- t2.time_seconds = rule2->at_time_seconds;
-
- /* FIXME: We don't know the offsets yet, but I don't think any Rules are
- close enough together that the offsets can make a difference. Should
- check this. */
- calculate_actual_time (&t1, TIME_WALL, 0, 0);
- calculate_actual_time (&t2, TIME_WALL, 0, 0);
-
- /* Now we can compare the entire time. */
- if (t1.year > t2.year)
- result = 1;
- else if (t1.year < t2.year)
- result = -1;
-
- else if (t1.month > t2.month)
- result = 1;
- else if (t1.month < t2.month)
- result = -1;
-
- else if (t1.day_number > t2.day_number)
- result = 1;
- else if (t1.day_number < t2.day_number)
- result = -1;
-
- else if (t1.time_seconds > t2.time_seconds)
- result = 1;
- else if (t1.time_seconds < t2.time_seconds)
- result = -1;
-
- else {
- printf ("WARNING: Rule dates matched.\n");
- result = 0;
- }
-
- return result;
-}
-
-
-static void
-output_zone (char *directory,
- ZoneData *zone,
- char *zone_name,
- GHashTable *rule_data)
-{
- FILE *fp, *changes_fp = NULL;
- char output_directory[PATHNAME_BUFFER_SIZE];
- char filename[PATHNAME_BUFFER_SIZE];
- char changes_filename[PATHNAME_BUFFER_SIZE];
- char *zone_directory, *zone_subdirectory, *zone_filename;
-
- /* Set a global for the zone_name, to be used only for debug messages. */
- CurrentZoneName = zone_name;
-
- /* Use this to only output a particular zone. */
-#if 0
- if (strcmp (zone_name, "Atlantic/Azores"))
- return;
-#endif
-
-#if 0
- printf ("Outputting Zone: %s\n", zone_name);
-#endif
-
- if (!parse_zone_name (zone_name, &zone_directory, &zone_subdirectory,
- &zone_filename))
- return;
-
- if (VzicDumpZoneNamesAndCoords) {
- VzicTimeZoneNames = g_list_prepend (VzicTimeZoneNames,
- g_strdup (zone_name));
- }
-
- sprintf (output_directory, "%s/%s", directory, zone_directory);
- ensure_directory_exists (output_directory);
- sprintf (filename, "%s/%s.ics", output_directory, zone_filename);
-
- if (VzicDumpChanges) {
- sprintf (output_directory, "%s/ChangesVzic/%s", directory, zone_directory);
- ensure_directory_exists (output_directory);
- sprintf (changes_filename, "%s/%s", output_directory, zone_filename);
- }
-
- if (zone_subdirectory) {
- sprintf (output_directory, "%s/%s/%s", directory, zone_directory,
- zone_subdirectory);
- ensure_directory_exists (output_directory);
- sprintf (filename, "%s/%s.ics", output_directory, zone_filename);
-
- if (VzicDumpChanges) {
- sprintf (output_directory, "%s/ChangesVzic/%s/%s", directory,
- zone_directory, zone_subdirectory);
- ensure_directory_exists (output_directory);
- sprintf (changes_filename, "%s/%s", output_directory, zone_filename);
- }
- }
-
- /* Create the files. */
- fp = fopen (filename, "w");
- if (!fp) {
- fprintf (stderr, "Couldn't create file: %s\n", filename);
- exit (1);
- }
-
- if (VzicDumpChanges) {
- changes_fp = fopen (changes_filename, "w");
- if (!changes_fp) {
- fprintf (stderr, "Couldn't create file: %s\n", changes_filename);
- exit (1);
- }
- }
-
- fprintf (fp, "BEGIN:VCALENDAR\nPRODID:%s\nVERSION:2.0\n", ProductID);
-
- output_zone_to_files (zone, zone_name, rule_data, fp, changes_fp);
-
- if (ferror (fp)) {
- fprintf (stderr, "Error writing file: %s\n", filename);
- exit (1);
- }
-
- fprintf (fp, "END:VCALENDAR\n");
-
- fclose (fp);
-
- g_free (zone_directory);
- g_free (zone_subdirectory);
- g_free (zone_filename);
-}
-
-
-/* This checks that the Zone name only uses the characters in [-+_/a-zA-Z0-9],
- and outputs a warning if it isn't. */
-static gboolean
-parse_zone_name (char *name,
- char **directory,
- char **subdirectory,
- char **filename)
-{
- static int invalid_zone_num = 1;
-
- char *p, ch, *first_slash_pos = NULL, *second_slash_pos = NULL;
- gboolean invalid = FALSE;
-
- for (p = name; (ch = *p) != 0; p++) {
- if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')
- && (ch < '0' || ch > '9') && ch != '/' && ch != '_'
- && ch != '-' && ch != '+') {
- fprintf (stderr, "WARNING: Unusual Zone name: %s\n", name);
- invalid = TRUE;
- break;
- }
-
- if (ch == '/') {
- if (!first_slash_pos) {
- first_slash_pos = p;
- } else if (!second_slash_pos) {
- second_slash_pos = p;
- } else {
- fprintf (stderr, "WARNING: More than 2 '/' characters in Zone name: %s\n", name);
- invalid = TRUE;
- break;
- }
- }
- }
-
- if (!first_slash_pos) {
-#if 0
- fprintf (stderr, "No '/' character in Zone name: %s. Skipping.\n", name);
-#endif
- return FALSE;
- }
-
- if (invalid) {
- *directory = g_strdup ("Invalid");
- *filename = g_strdup_printf ("Zone%i", invalid_zone_num++);
- } else {
- *first_slash_pos = '\0';
- *directory = g_strdup (name);
- *first_slash_pos = '/';
-
- if (second_slash_pos) {
- *second_slash_pos = '\0';
- *subdirectory = g_strdup (first_slash_pos + 1);
- *second_slash_pos = '/';
-
- *filename = g_strdup (second_slash_pos + 1);
- } else {
- *subdirectory = NULL;
- *filename = g_strdup (first_slash_pos + 1);
- }
- }
-
- return invalid ? FALSE : TRUE;
-}
-
-
-static void
-output_zone_to_files (ZoneData *zone,
- char *zone_name,
- GHashTable *rule_data,
- FILE *fp,
- FILE *changes_fp)
-{
- ZoneLineData *zone_line;
- GArray *changes;
- int i, stdoff, walloff, start_index, save_seconds;
- VzicTime start, end, *vzictime_start, *vzictime, *vzictime_first_rule_change;
- gboolean is_daylight, found_letter_s;
- char *start_letter_s;
-
- changes = g_array_new (FALSE, FALSE, sizeof (VzicTime));
-
- vzictime_init (&start);
- vzictime_init (&end);
-
- /* The first period starts at -infinity. */
- start.year = YEAR_MINIMUM;
-
- for (i = 0; i < zone->zone_line_data->len; i++) {
- zone_line = &g_array_index (zone->zone_line_data, ZoneLineData, i);
-
- /* This is the local standard time offset from GMT for this period. */
- start.stdoff = stdoff = zone_line->stdoff_seconds;
- start.walloff = walloff = stdoff + zone_line->save_seconds;
-
- if (zone_line->until_set) {
- end.year = zone_line->until_year;
- end.month = zone_line->until_month;
- end.day_code = zone_line->until_day_code;
- end.day_number = zone_line->until_day_number;
- end.day_weekday = zone_line->until_day_weekday;
- end.time_seconds = zone_line->until_time_seconds;
- end.time_code = zone_line->until_time_code;
- } else {
- /* The last period ends at +infinity. */
- end.year = YEAR_MAXIMUM;
- }
-
- /* Add a time change for the start of the period. This may be removed
- later if one of the rules expands to exactly the same time. */
- start_index = changes->len;
- g_array_append_val (changes, start);
-
- /* If there are Rules associated with this period, add all the relevant
- time changes. */
- save_seconds = 0;
- if (zone_line->rules)
- found_letter_s = add_rule_changes (zone_line, zone_name, changes,
- rule_data, &start, &end,
- &start_letter_s, &save_seconds);
- else
- found_letter_s = FALSE;
-
- /* FIXME: I'm not really sure what to do about finding a LETTER_S for the
- first part of the period (i.e. before the first Rule comes into effect).
- Currently we try to use the same LETTER_S as the first Rule of the
- period which is in local standard time. */
- if (zone_line->save_seconds)
- save_seconds = zone_line->save_seconds;
- is_daylight = save_seconds ? TRUE : FALSE;
- vzictime_start = &g_array_index (changes, VzicTime, start_index);
- walloff = vzictime_start->walloff = stdoff + save_seconds;
-
- /* TEST: See if the first Rule time is exactly the same as the change from
- the Zone line. In which case we can remove the Zone line change. */
- if (changes->len > start_index + 1) {
- int prev_stdoff, prev_walloff;
-
- if (start_index > 0) {
- VzicTime *v = &g_array_index (changes, VzicTime, start_index - 1);
- prev_stdoff = v->stdoff;
- prev_walloff = v->walloff;
- } else {
- prev_stdoff = 0;
- prev_walloff = 0;
- }
- vzictime_first_rule_change = &g_array_index (changes, VzicTime,
- start_index + 1);
- if (times_match (vzictime_start, prev_stdoff, prev_walloff,
- vzictime_first_rule_change, stdoff, walloff)) {
-#if 0
- printf ("Removing zone-line change (using new offsets)\n");
-#endif
- g_array_remove_index (changes, start_index);
- vzictime_start = NULL;
- } else if (times_match (vzictime_start, prev_stdoff, prev_walloff,
- vzictime_first_rule_change, prev_stdoff, prev_walloff)) {
-#if 0
- printf ("Removing zone-line change (using previous offsets)\n");
-#endif
- g_array_remove_index (changes, start_index);
- vzictime_start = NULL;
- }
- }
-
-
- if (vzictime_start) {
- vzictime_start->tzname = expand_tzname (zone_name, zone_line->format,
- found_letter_s,
- start_letter_s, is_daylight);
- }
-
- /* The start of the next Zone line is the end time of this one. */
- start = end;
- }
-
- set_previous_offsets (changes);
-
- output_zone_components (fp, zone_name, changes);
-
- if (VzicDumpChanges)
- dump_changes (changes_fp, zone_name, changes);
-
- /* Free all the TZNAME fields. */
- for (i = 0; i < changes->len; i++) {
- vzictime = &g_array_index (changes, VzicTime, i);
- g_free (vzictime->tzname);
- }
-
- g_array_free (changes, TRUE);
-}
-
-
-/* This appends any timezone changes specified by the rules associated with
- the timezone, that happen between the start and end times.
- It returns the letter_s field of the first STANDARD rule found in the
- search. We need this to fill in any %s in the FORMAT field of the first
- component of the time period (the Zone line). */
-static gboolean
-add_rule_changes (ZoneLineData *zone_line,
- char *zone_name,
- GArray *changes,
- GHashTable *rule_data,
- VzicTime *start,
- VzicTime *end,
- char **start_letter_s,
- int *save_seconds)
-{
- GArray *rule_array;
- RuleData *rule, *prev_rule = NULL;
- int stdoff, walloff, i, prev_stdoff, prev_walloff;
- VzicTime vzictime;
- gboolean is_daylight, found_start_letter_s = FALSE;
- gboolean checked_for_previous = FALSE;
-
- *save_seconds = 0;
-
- rule_array = g_hash_table_lookup (rule_data, zone_line->rules);
- if (!rule_array) {
- fprintf (stderr, "Couldn't access rules: %s\n", zone_line->rules);
- exit (1);
- }
-
- /* The stdoff is the same for all the rules. */
- stdoff = start->stdoff;
-
- /* The walloff changes as we go through the rules. */
- walloff = start->walloff;
-
- /* Get the stdoff & walloff from the last change before this period. */
- if (changes->len >= 2) {
- VzicTime *change = &g_array_index (changes, VzicTime, changes->len - 2);
- prev_stdoff = change->stdoff;
- prev_walloff = change->walloff;
- } else {
- prev_stdoff = prev_walloff = 0;
- }
-
-
- for (i = 0; i < rule_array->len; i++) {
- rule = &g_array_index (rule_array, RuleData, i);
-
- is_daylight = rule->save_seconds != 0 ? TRUE : FALSE;
-
- vzictime_init (&vzictime);
- vzictime.year = rule->from_year;
- vzictime.month = rule->in_month;
- vzictime.day_code = rule->on_day_code;
- vzictime.day_number = rule->on_day_number;
- vzictime.day_weekday = rule->on_day_weekday;
- vzictime.time_seconds = rule->at_time_seconds;
- vzictime.time_code = rule->at_time_code;
- vzictime.stdoff = stdoff;
- vzictime.walloff = stdoff + rule->save_seconds;
- vzictime.is_infinite = (rule->to_year == YEAR_MAXIMUM) ? TRUE : FALSE;
-
- /* If the rule time is before the given start time, skip it. */
- if (compare_times (&vzictime, stdoff, walloff,
- start, prev_stdoff, prev_walloff) < 0)
- continue;
-
- /* If the previous Rule was a daylight Rule, then we may want to use the
- walloff from that. */
- if (!checked_for_previous) {
- checked_for_previous = TRUE;
- if (i > 0) {
- prev_rule = &g_array_index (rule_array, RuleData, i - 1);
- if (prev_rule->save_seconds) {
- walloff = start->walloff = stdoff + prev_rule->save_seconds;
- *save_seconds = prev_rule->save_seconds;
- found_start_letter_s = TRUE;
- *start_letter_s = prev_rule->letter_s;
-#if 0
- printf ("Could use save_seconds from previous Rule: %s\n",
- zone_name);
-#endif
- }
- }
- }
-
- /* If an end time has been given, then if the rule time is on or after it
- break out of the loop. */
- if (end->year != YEAR_MAXIMUM
- && compare_times (&vzictime, stdoff, walloff,
- end, stdoff, walloff) >= 0)
- break;
-
- vzictime.tzname = expand_tzname (zone_name, zone_line->format, TRUE,
- rule->letter_s, is_daylight);
-
- g_array_append_val (changes, vzictime);
-
- /* When we find the first STANDARD time we set letter_s. */
- if (!found_start_letter_s && !is_daylight) {
- found_start_letter_s = TRUE;
- *start_letter_s = rule->letter_s;
- }
-
- /* Now that we have added the Rule, the new walloff comes into effect
- for any following Rules. */
- walloff = vzictime.walloff;
- }
-
- return found_start_letter_s;
-}
-
-
-/* This expands the Zone line FORMAT field, using the given LETTER_S from a
- Rule line. There are 3 types of FORMAT field:
- 1. a string with an %s in, e.g. "WE%sT". The %s is replaced with LETTER_S.
- 2. a string with an '/' in, e.g. "CAT/CAWT". The first part is used for
- standard time and the second part for when daylight-saving is in effect.
- 3. a plain string, e.g. "LMT", which we leave as-is.
- Note that (1) is the only type in which letter_s is required.
-*/
-static char*
-expand_tzname (char *zone_name,
- char *format,
- gboolean have_letter_s,
- char *letter_s,
- gboolean is_daylight)
-{
- char *p, buffer[256], *guess = NULL;
- int len;
-
-#if 0
- printf ("Expanding %s with %s\n", format, letter_s);
-#endif
-
- if (!format || !format[0]) {
- fprintf (stderr, "Missing FORMAT\n");
- exit (1);
- }
-
- /* 1. Look for a "%s". */
- p = strchr (format, '%');
- if (p && *(p + 1) == 's') {
- if (!have_letter_s) {
-
- /* NOTE: These are a few hard-coded TZNAMEs that I've looked up myself.
- These are needed in a few places where a Zone line comes into effect
- but no Rule has been found, so we have no LETTER_S to use.
- I've tried to use whatever is the normal LETTER_S in the Rules for
- the particular zone, in local standard time. */
- if (!strcmp (zone_name, "Asia/Macao")
- && !strcmp (format, "C%sT"))
- guess = "CST";
- else if (!strcmp (zone_name, "Asia/Macau")
- && !strcmp (format, "C%sT"))
- guess = "CST";
- else if (!strcmp (zone_name, "Asia/Ashgabat")
- && !strcmp (format, "ASH%sT"))
- guess = "ASHT";
- else if (!strcmp (zone_name, "Asia/Ashgabat")
- && !strcmp (format, "TM%sT"))
- guess = "TMT";
- else if (!strcmp (zone_name, "Asia/Samarkand")
- && !strcmp (format, "TAS%sT"))
- guess = "TAST";
- else if (!strcmp (zone_name, "Atlantic/Azores")
- && !strcmp (format, "WE%sT"))
- guess = "WET";
- else if (!strcmp (zone_name, "Europe/Paris")
- && !strcmp (format, "WE%sT"))
- guess = "WET";
- else if (!strcmp (zone_name, "Europe/Warsaw")
- && !strcmp (format, "CE%sT"))
- guess = "CET";
- else if (!strcmp (zone_name, "America/Phoenix")
- && !strcmp (format, "M%sT"))
- guess = "MST";
- else if (!strcmp (zone_name, "America/Nome")
- && !strcmp (format, "Y%sT"))
- guess = "YST";
-
- if (guess) {
-#if 0
- fprintf (stderr,
- "WARNING: Couldn't find a LETTER_S to use in FORMAT: %s in Zone: %s Guessing: %s\n",
- format, zone_name, guess);
-#endif
- return g_strdup (guess);
- }
-
-#if 1
- fprintf (stderr,
- "WARNING: Couldn't find a LETTER_S to use in FORMAT: %s in Zone: %s Leaving TZNAME empty\n",
- format, zone_name);
-#endif
-
-#if 0
- /* This is useful to spot exactly which component had a problem. */
- sprintf (buffer, "FIXME: %s", format);
- return g_strdup (buffer);
-#else
- /* We give up and don't output a TZNAME. */
- return NULL;
-#endif
- }
-
- sprintf (buffer, format, letter_s ? letter_s : "");
- return g_strdup (buffer);
- }
-
- /* 2. Look for a "/". */
- p = strchr (format, '/');
- if (p) {
- if (is_daylight) {
- return g_strdup (p + 1);
- } else {
- len = p - format;
- strncpy (buffer, format, len);
- buffer[len] = '\0';
- return g_strdup (buffer);
- }
- }
-
- /* 3. Just use format as it is. */
- return g_strdup (format);
-}
-
-
-/* Compares 2 VzicTimes, returning strcmp()-like values, i.e. 0 if equal,
- 1 if the 1st is after the 2nd and -1 if the 1st is before the 2nd. */
-static int
-compare_times (VzicTime *time1,
- int stdoff1,
- int walloff1,
- VzicTime *time2,
- int stdoff2,
- int walloff2)
-{
- VzicTime t1, t2;
- int result;
-
- t1 = *time1;
- t2 = *time2;
-
- calculate_actual_time (&t1, TIME_UNIVERSAL, stdoff1, walloff1);
- calculate_actual_time (&t2, TIME_UNIVERSAL, stdoff2, walloff2);
-
- /* Now we can compare the entire time. */
- if (t1.year > t2.year)
- result = 1;
- else if (t1.year < t2.year)
- result = -1;
-
- else if (t1.month > t2.month)
- result = 1;
- else if (t1.month < t2.month)
- result = -1;
-
- else if (t1.day_number > t2.day_number)
- result = 1;
- else if (t1.day_number < t2.day_number)
- result = -1;
-
- else if (t1.time_seconds > t2.time_seconds)
- result = 1;
- else if (t1.time_seconds < t2.time_seconds)
- result = -1;
-
- else
- result = 0;
-
-#if 0
- printf ("%i/%i/%i %i <=> %i/%i/%i %i -> %i\n",
- t1.day_number, t1.month + 1, t1.year, t1.time_seconds,
- t2.day_number, t2.month + 1, t2.year, t2.time_seconds,
- result);
-#endif
-
- return result;
-}
-
-
-/* Returns TRUE if the 2 times are exactly the same. It will calculate the
- actual day, but doesn't convert times. */
-static gboolean
-times_match (VzicTime *time1,
- int stdoff1,
- int walloff1,
- VzicTime *time2,
- int stdoff2,
- int walloff2)
-{
- VzicTime t1, t2;
-
- t1 = *time1;
- t2 = *time2;
-
- calculate_actual_time (&t1, TIME_UNIVERSAL, stdoff1, walloff1);
- calculate_actual_time (&t2, TIME_UNIVERSAL, stdoff2, walloff2);
-
- if (t1.year == t2.year
- && t1.month == t2.month
- && t1.day_number == t2.day_number
- && t1.time_seconds == t2.time_seconds)
- return TRUE;
-
- return FALSE;
-}
-
-
-static void
-output_zone_components (FILE *fp,
- char *name,
- GArray *changes)
-{
- VzicTime *vzictime;
- int i, start_index = 0;
- gboolean only_one_change = FALSE;
- char start_buffer[1024];
-
- fprintf (fp, "BEGIN:VTIMEZONE\nTZID:%s%s\n", TZIDPrefixExpanded, name);
-
- if (VzicUrlPrefix != NULL)
- fprintf (fp, "TZURL:%s/%s\n", VzicUrlPrefix, name);
-
- /* We use an 'X-' property to place the city name in. */
- fprintf (fp, "X-LIC-LOCATION:%s\n", name);
-
- /* We try to find any recurring components first, or they may get output
- as lots of RDATES instead. */
- if (!VzicNoRRules) {
- int num_rrules_output = 0;
-
- for (i = 1; i < changes->len; i++) {
- if (check_for_recurrence (fp, changes, i)) {
- num_rrules_output++;
- }
- }
-
-#if 0
- printf ("Zone: %s had %i infinite RRULEs\n", CurrentZoneName,
- num_rrules_output);
-#endif
-
- if (!VzicPureOutput && num_rrules_output == 2) {
-#if 0
- printf ("Zone: %s using 2 RRULEs\n", CurrentZoneName);
-#endif
- fprintf (fp, "END:VTIMEZONE\n");
- return;
- }
- }
-
- /* We skip the first change, which starts at -infinity, unless it is the only
- change for the timezone. */
- if (changes->len > 1)
- start_index = 1;
- else
- only_one_change = TRUE;
-
- /* For pure output, we start at the start of the array and step through it
- outputting RDATEs. For Outlook-compatible output we start at the end
- and step backwards to find the first STANDARD time to output. */
- if (VzicPureOutput)
- i = start_index - 1;
- else
- i = changes->len;
-
- for (;;) {
- if (VzicPureOutput)
- i++;
- else
- i--;
-
- if (VzicPureOutput) {
- if (i >= changes->len)
- break;
- } else {
- if (i < start_index)
- break;
- }
-
- vzictime = &g_array_index (changes, VzicTime, i);
-
- /* If we have already output this component as part of an RRULE or RDATE,
- then we skip it. */
- if (vzictime->output)
- continue;
-
- /* For Outlook-compatible output we only want to output the last STANDARD
- time as a DTSTART, so skip any DAYLIGHT changes. */
- if (!VzicPureOutput && vzictime->stdoff != vzictime->walloff) {
- printf ("Skipping DAYLIGHT change\n");
- continue;
- }
-
-#if 0
- printf ("Zone: %s using DTSTART Year: %i\n", CurrentZoneName,
- vzictime->year);
-#endif
-
- if (VzicPureOutput) {
- output_component_start (start_buffer, vzictime, TRUE, only_one_change);
- } else {
- /* For Outlook compatability we don't output the RDATE and use the same
- TZOFFSET for TZOFFSETFROM and TZOFFSETTO. */
- vzictime->year = RDATE_YEAR;
- vzictime->month = 0;
- vzictime->day_code = DAY_SIMPLE;
- vzictime->day_number = 1;
- vzictime->time_code = TIME_WALL;
- vzictime->time_seconds = 0;
-
- output_component_start (start_buffer, vzictime, FALSE, TRUE);
- }
-
- fprintf (fp, "%s", start_buffer);
-
- /* This will look for matching components and output them as RDATEs
- instead of separate components. */
- if (VzicPureOutput && !VzicNoRDates)
- check_for_rdates (fp, changes, i);
-
- output_component_end (fp, vzictime);
-
- vzictime->output = TRUE;
-
- if (!VzicPureOutput)
- break;
- }
-
- fprintf (fp, "END:VTIMEZONE\n");
-}
-
-
-/* This sets the prev_stdoff and prev_walloff (i.e. the TZOFFSETFROM) of each
- VzicTime, using the stdoff and walloff of the previous VzicTime. It makes
- the rest of the code much simpler. */
-static void
-set_previous_offsets (GArray *changes)
-{
- VzicTime *vzictime, *prev_vzictime;
- int i;
-
- prev_vzictime = &g_array_index (changes, VzicTime, 0);
- prev_vzictime->prev_stdoff = 0;
- prev_vzictime->prev_walloff = 0;
-
- for (i = 1; i < changes->len; i++) {
- vzictime = &g_array_index (changes, VzicTime, i);
-
- vzictime->prev_stdoff = prev_vzictime->stdoff;
- vzictime->prev_walloff = prev_vzictime->walloff;
-
- prev_vzictime = vzictime;
- }
-}
-
-
-/* Returns TRUE if we output an infinite recurrence. */
-static gboolean
-check_for_recurrence (FILE *fp,
- GArray *changes,
- int idx)
-{
- VzicTime *vzictime_start, *vzictime, vzictime_start_copy;
- gboolean is_daylight_start, is_daylight;
- int last_match, i, next_year, day_offset;
- char until[256], rrule_buffer[2048], start_buffer[1024];
- GList *matching_elements = NULL, *elem;
-
- vzictime_start = &g_array_index (changes, VzicTime, idx);
-
- /* If this change has already been output, skip it. */
- if (vzictime_start->output)
- return FALSE;
-
- /* There can't possibly be an RRULE starting from YEAR_MINIMUM. */
- if (vzictime_start->year == YEAR_MINIMUM)
- return FALSE;
-
- is_daylight_start = (vzictime_start->stdoff != vzictime_start->walloff)
- ? TRUE : FALSE;
-
-#if 0
- printf ("\nChecking: %s OFFSETFROM: %i %s\n",
- format_vzictime (vzictime_start), vzictime_start->prev_walloff,
- is_daylight_start ? "DAYLIGHT" : "");
-#endif
-
- /* If this is an infinitely recurring change, output the RRULE and return.
- There won't be any changes after it that we could merge. */
- if (vzictime_start->is_infinite) {
-
- /* Change the year to our minimum start year. */
- vzictime_start_copy = *vzictime_start;
- if (!VzicPureOutput)
- vzictime_start_copy.year = RRULE_START_YEAR;
-
- day_offset = output_component_start (start_buffer, &vzictime_start_copy,
- FALSE, FALSE);
-
- if (!output_rrule (rrule_buffer, vzictime_start_copy.month,
- vzictime_start_copy.day_code,
- vzictime_start_copy.day_number,
- vzictime_start_copy.day_weekday, day_offset, "")) {
- if (vzictime_start->year != MAX_TIME_T_YEAR) {
- fprintf (stderr, "WARNING: Failed to output infinite recurrence with start year: %i\n", vzictime_start->year);
- }
- return TRUE;
- }
-
- fprintf (fp, "%s%s", start_buffer, rrule_buffer);
- output_component_end (fp, vzictime_start);
- vzictime_start->output = TRUE;
- return TRUE;
- }
-
- last_match = idx;
- next_year = vzictime_start->year + 1;
- for (i = idx + 1; i < changes->len; i++) {
- vzictime = &g_array_index (changes, VzicTime, i);
-
- is_daylight = (vzictime->stdoff != vzictime->walloff) ? TRUE : FALSE;
-
- if (vzictime->output)
- continue;
-
-#if 0
- printf (" %s OFFSETFROM: %i %s\n",
- format_vzictime (vzictime), vzictime->prev_walloff,
- is_daylight ? "DAYLIGHT" : "");
-#endif
-
- /* If it is more than one year ahead, we are finished, since we want
- consecutive years. */
- if (vzictime->year > next_year) {
- break;
- }
-
- /* It must be the same type of component - STANDARD or DAYLIGHT. */
- if (is_daylight != is_daylight_start) {
- continue;
- }
-
- /* It must be the following year, with the same month, day & time.
- It is possible that the time has a different code but does in fact
- match when normalized, but we don't care (for now at least). */
- if (vzictime->year != next_year
- || vzictime->month != vzictime_start->month
- || vzictime->day_code != vzictime_start->day_code
- || vzictime->day_number != vzictime_start->day_number
- || vzictime->day_weekday != vzictime_start->day_weekday
- || vzictime->time_seconds != vzictime_start->time_seconds
- || vzictime->time_code != vzictime_start->time_code) {
- continue;
- }
-
- /* The TZOFFSETFROM and TZOFFSETTO must match. */
- if (vzictime->prev_walloff != vzictime_start->prev_walloff) {
- continue;
- }
-
- if (vzictime->walloff != vzictime_start->walloff) {
- continue;
- }
-
- /* TZNAME must match. */
- if (!timezones_match (vzictime->tzname, vzictime_start->tzname)) {
- continue;
- }
-
- /* We have a match. */
- last_match = i;
- next_year = vzictime->year + 1;
-
- matching_elements = g_list_prepend (matching_elements, vzictime);
- }
-
- if (last_match == idx)
- return FALSE;
-
-#if 0
- printf ("Found recurrence %i - %i!!!\n", vzictime_start->year,
- next_year - 1);
-#endif
-
- vzictime = &g_array_index (changes, VzicTime, last_match);
-
-/* We only use RRULEs if there are at least MIN_RRULE_OCCURRENCES occurrences,
- since otherwise RDATEs are more efficient. */
- if (!vzictime->is_infinite) {
- int years = vzictime->year - vzictime_start->year + 1;
-#if 0
- printf ("RRULE Years: %i\n", years);
-#endif
- if (years < MIN_RRULE_OCCURRENCES)
- return FALSE;
- }
-
- if (vzictime->is_infinite) {
- until[0] = '\0';
- } else {
- VzicTime t1 = *vzictime;
-
- printf ("RRULE with UNTIL - aborting\n");
- abort ();
-
- calculate_actual_time (&t1, TIME_UNIVERSAL, vzictime->prev_stdoff,
- vzictime->prev_walloff);
-
- /* Output UNTIL, in UTC. */
- sprintf (until, ";UNTIL=%sZ", format_time (t1.year, t1.month,
- t1.day_number,
- t1.time_seconds));
- }
-
- /* Change the year to our minimum start year. */
- vzictime_start_copy = *vzictime_start;
- if (!VzicPureOutput)
- vzictime_start_copy.year = RRULE_START_YEAR;
-
- day_offset = output_component_start (start_buffer, &vzictime_start_copy,
- FALSE, FALSE);
- if (output_rrule (rrule_buffer, vzictime_start_copy.month,
- vzictime_start_copy.day_code,
- vzictime_start_copy.day_number,
- vzictime_start_copy.day_weekday, day_offset, until)) {
- fprintf (fp, "%s%s", start_buffer, rrule_buffer);
- output_component_end (fp, vzictime_start);
-
- /* Mark all the changes as output. */
- vzictime_start->output = TRUE;
- for (elem = matching_elements; elem; elem = elem->next) {
- vzictime = elem->data;
- vzictime->output = TRUE;
- }
- }
-
- g_list_free (matching_elements);
-
- return TRUE;
-}
-
-
-static void
-check_for_rdates (FILE *fp,
- GArray *changes,
- int idx)
-{
- VzicTime *vzictime_start, *vzictime, tmp_vzictime;
- gboolean is_daylight_start, is_daylight;
- int i, year, month, day, time;
-
- vzictime_start = &g_array_index (changes, VzicTime, idx);
-
- is_daylight_start = (vzictime_start->stdoff != vzictime_start->walloff)
- ? TRUE : FALSE;
-
-#if 0
- printf ("\nChecking: %s OFFSETFROM: %i %s\n",
- format_vzictime (vzictime_start), vzictime_start->prev_walloff,
- is_daylight_start ? "DAYLIGHT" : "");
-#endif
-
- /* We want to go backwards through the array now, for Outlook compatability.
- (It only looks at the first DTSTART/RDATE.) */
- for (i = idx + 1; i < changes->len; i++) {
- vzictime = &g_array_index (changes, VzicTime, i);
-
- is_daylight = (vzictime->stdoff != vzictime->walloff) ? TRUE : FALSE;
-
- if (vzictime->output)
- continue;
-
-#if 0
- printf (" %s OFFSETFROM: %i %s\n", format_vzictime (vzictime),
- vzictime->prev_walloff, is_daylight ? "DAYLIGHT" : "");
-#endif
-
- /* It must be the same type of component - STANDARD or DAYLIGHT. */
- if (is_daylight != is_daylight_start) {
- continue;
- }
-
- /* The TZOFFSETFROM and TZOFFSETTO must match. */
- if (vzictime->prev_walloff != vzictime_start->prev_walloff) {
- continue;
- }
-
- if (vzictime->walloff != vzictime_start->walloff) {
- continue;
- }
-
- /* TZNAME must match. */
- if (!timezones_match (vzictime->tzname, vzictime_start->tzname)) {
- continue;
- }
-
- /* We have a match. */
-
- tmp_vzictime = *vzictime;
- calculate_actual_time (&tmp_vzictime, TIME_WALL, vzictime->prev_stdoff,
- vzictime->prev_walloff);
-
- fprintf (fp, "RDATE:%s\n", format_time (tmp_vzictime.year,
- tmp_vzictime.month,
- tmp_vzictime.day_number,
- tmp_vzictime.time_seconds));
-
- vzictime->output = TRUE;
- }
-}
-
-
-static gboolean
-timezones_match (char *tzname1,
- char *tzname2)
-{
- if (tzname1 && tzname2 && !strcmp (tzname1, tzname2))
- return TRUE;
-
- if (!tzname1 && !tzname2)
- return TRUE;
-
- return FALSE;
-}
-
-
-/* Outputs the start of a VTIMEZONE component, with the BEGIN line,
- the DTSTART, TZOFFSETFROM, TZOFFSETTO & TZNAME properties. */
-static int
-output_component_start (char *buffer,
- VzicTime *vzictime,
- gboolean output_rdate,
- gboolean use_same_tz_offset)
-{
- gboolean is_daylight, skip_day_offset = FALSE;
- gint year, month, day, time, day_offset = 0;
- GDate old_date, new_date;
- char *formatted_time;
- char line1[1024], line2[1024], line3[1024];
- char line4[1024], line5[1024], line6[1024];
- VzicTime tmp_vzictime;
- int prev_walloff;
-
- is_daylight = (vzictime->stdoff != vzictime->walloff) ? TRUE : FALSE;
-
- tmp_vzictime = *vzictime;
- day_offset = calculate_actual_time (&tmp_vzictime, TIME_WALL,
- vzictime->prev_stdoff,
- vzictime->prev_walloff);
-
- sprintf (line1, "BEGIN:%s\n", is_daylight ? "DAYLIGHT" : "STANDARD");
-
- /* If the timezone only has one change, that means it uses the same offset
- forever, so we use the same TZOFFSETFROM as the TZOFFSETTO. (If the zone
- has more than one change, we don't output the first one.) */
- if (use_same_tz_offset)
- prev_walloff = vzictime->walloff;
- else
- prev_walloff = vzictime->prev_walloff;
-
- sprintf (line2, "TZOFFSETFROM:%s\n",
- format_tz_offset (prev_walloff, !VzicPureOutput));
-
- sprintf (line3, "TZOFFSETTO:%s\n",
- format_tz_offset (vzictime->walloff, !VzicPureOutput));
-
- if (vzictime->tzname)
- sprintf (line4, "TZNAME:%s\n", vzictime->tzname);
- else
- line4[0] = '\0';
-
- formatted_time = format_time (tmp_vzictime.year, tmp_vzictime.month,
- tmp_vzictime.day_number,
- tmp_vzictime.time_seconds);
- sprintf (line5, "DTSTART:%s\n", formatted_time);
- if (output_rdate)
- sprintf (line6, "RDATE:%s\n", formatted_time);
- else
- line6[0] = '\0';
-
- sprintf (buffer, "%s%s%s%s%s%s", line1, line2, line3, line4, line5, line6);
-
- return day_offset;
-}
-
-
-/* Outputs the END line of the VTIMEZONE component. */
-static void
-output_component_end (FILE *fp,
- VzicTime *vzictime)
-{
- gboolean is_daylight;
-
- is_daylight = (vzictime->stdoff != vzictime->walloff) ? TRUE : FALSE;
-
- fprintf (fp, "END:%s\n", is_daylight ? "DAYLIGHT" : "STANDARD");
-}
-
-
-/* Initializes a VzicTime to 1st Jan in YEAR_MINIMUM at midnight, with all
- offsets set to 0. */
-static void
-vzictime_init (VzicTime *vzictime)
-{
- vzictime->year = YEAR_MINIMUM;
- vzictime->month = 0;
- vzictime->day_code = DAY_SIMPLE;
- vzictime->day_number = 1;
- vzictime->day_weekday = 0;
- vzictime->time_seconds = 0;
- vzictime->time_code = TIME_UNIVERSAL;
- vzictime->stdoff = 0;
- vzictime->walloff = 0;
- vzictime->is_infinite = FALSE;
- vzictime->output = FALSE;
- vzictime->prev_stdoff = 0;
- vzictime->prev_walloff = 0;
- vzictime->tzname = NULL;
-}
-
-
-/* This calculates the actual local time that a change will occur, given
- the offsets from standard and wall-clock time. It returns -1 or 1 if it
- had to move backwards or forwards one day while converting to local time.
- If it does this then we need to change the RRULEs we output. */
-static int
-calculate_actual_time (VzicTime *vzictime,
- TimeCode time_code,
- int stdoff,
- int walloff)
-{
- GDate date;
- gint day_offset, days_in_month, weekday, offset, result;
-
- vzictime->time_seconds = calculate_wall_time (vzictime->time_seconds,
- vzictime->time_code,
- stdoff, walloff, &day_offset);
-
- if (vzictime->day_code != DAY_SIMPLE) {
- if (vzictime->year == YEAR_MINIMUM || vzictime->year == YEAR_MAXIMUM) {
- fprintf (stderr, "In calculate_actual_time: invalid year\n");
- exit (0);
- }
-
- g_date_clear (&date, 1);
- days_in_month = g_date_days_in_month (vzictime->month + 1, vzictime->year);
-
- /* Note that the day_code refers to the date before we convert it to
- a wall-clock date and time. So we find the day it was referring to,
- then make any adjustments needed due to converting the time. */
- if (vzictime->day_code == DAY_LAST_WEEKDAY) {
- /* Find out what day the last day of the month is. */
- g_date_set_dmy (&date, days_in_month, vzictime->month + 1,
- vzictime->year);
- weekday = g_date_weekday (&date) % 7;
-
- /* Calculate how many days we have to go back to get to day_weekday. */
- offset = (weekday + 7 - vzictime->day_weekday) % 7;
-
- vzictime->day_number = days_in_month - offset;
- } else {
- /* Find out what day day_number actually is. */
- g_date_set_dmy (&date, vzictime->day_number, vzictime->month + 1,
- vzictime->year);
- weekday = g_date_weekday (&date) % 7;
-
- if (vzictime->day_code == DAY_WEEKDAY_ON_OR_AFTER)
- offset = (vzictime->day_weekday + 7 - weekday) % 7;
- else
- offset = - ((weekday + 7 - vzictime->day_weekday) % 7);
-
- vzictime->day_number = vzictime->day_number + offset;
- }
-
- vzictime->day_code = DAY_SIMPLE;
-
- if (vzictime->day_number <= 0 || vzictime->day_number > days_in_month) {
- fprintf (stderr, "Day overflow: %i\n", vzictime->day_number);
- exit (1);
- }
- }
-
-#if 0
- fprintf (stderr, "%s -> %i/%i/%i\n",
- dump_day_coded (vzictime->day_code, vzictime->day_number,
- vzictime->day_weekday),
- vzictime->day_number, vzictime->month + 1, vzictime->year);
-#endif
-
- fix_time_overflow (&vzictime->year, &vzictime->month,
- &vzictime->day_number, day_offset);
-
- /* If we want UTC time, we have to convert it now. */
- if (time_code == TIME_UNIVERSAL) {
- vzictime->time_seconds = calculate_until_time (vzictime->time_seconds,
- TIME_WALL, stdoff, walloff,
- &vzictime->year,
- &vzictime->month,
- &vzictime->day_number);
- }
-
- return day_offset;
-}
-
-
-/* This converts the given time into universal time (UTC), to be used in
- the UNTIL property. */
-static int
-calculate_until_time (int time,
- TimeCode time_code,
- int stdoff,
- int walloff,
- int *year,
- int *month,
- int *day)
-{
- int result, day_offset;
-
- day_offset = 0;
-
- switch (time_code) {
- case TIME_WALL:
- result = time - walloff;
- break;
- case TIME_STANDARD:
- result = time - stdoff;
- break;
- case TIME_UNIVERSAL:
- return time;
- default:
- fprintf (stderr, "Invalid time code\n");
- exit (1);
- }
-
- if (result < 0) {
- result += 24 * 60 * 60;
- day_offset = -1;
- } else if (result >= 24 * 60 * 60) {
- result -= 24 * 60 * 60;
- day_offset = 1;
- }
-
- /* Sanity check - we shouldn't have an overflow any more. */
- if (result < 0 || result >= 24 * 60 * 60) {
- fprintf (stderr, "Time overflow: %i\n", result);
- abort ();
- }
-
- fix_time_overflow (year, month, day, day_offset);
-
- return result;
-}
-
-
-/* This converts the given time into wall clock time (the local standard time
- with any adjustment for daylight-saving). */
-static int
-calculate_wall_time (int time,
- TimeCode time_code,
- int stdoff,
- int walloff,
- int *day_offset)
-{
- int result;
-
- *day_offset = 0;
-
- switch (time_code) {
- case TIME_WALL:
- return time;
- case TIME_STANDARD:
- /* We have a local standard time, so we have to subtract stdoff to get
- back to UTC, then add walloff to get wall time. */
- result = time - stdoff + walloff;
- break;
- case TIME_UNIVERSAL:
- result = time + walloff;
- break;
- default:
- fprintf (stderr, "Invalid time code\n");
- exit (1);
- }
-
- if (result < 0) {
- result += 24 * 60 * 60;
- *day_offset = -1;
- } else if (result >= 24 * 60 * 60) {
- result -= 24 * 60 * 60;
- *day_offset = 1;
- }
-
- /* Sanity check - we shouldn't have an overflow any more. */
- if (result < 0 || result >= 24 * 60 * 60) {
- fprintf (stderr, "Time overflow: %i\n", result);
- exit (1);
- }
-
-#if 0
- printf ("%s -> ", dump_time (time, time_code, TRUE));
- printf ("%s (%i)\n", dump_time (result, TIME_WALL, TRUE), *day_offset);
-#endif
-
- return result;
-}
-
-
-static void
-fix_time_overflow (int *year,
- int *month,
- int *day,
- int day_offset)
-{
- if (day_offset == -1) {
- *day = *day - 1;
-
- if (*day == 0) {
- *month = *month - 1;
- if (*month == -1) {
- *month = 11;
- *year = *year - 1;
- }
- *day = g_date_days_in_month (*month + 1, *year);
- }
- } else if (day_offset == 1) {
- *day = *day + 1;
-
- if (*day > g_date_days_in_month (*month + 1, *year)) {
- *month = *month + 1;
- if (*month == 12) {
- *month = 0;
- *year = *year + 1;
- }
- *day = 1;
- }
- }
-}
-
-
-static char*
-format_time (int year,
- int month,
- int day,
- int time)
-{
- static char buffer[128];
- int hour, minute, second;
-
- /* When we are outputting the first component year will be YEAR_MINIMUM.
- We used to use 1 when outputting this, but Outlook doesn't like any years
- less that 1600, so we use 1600 instead. We don't output the first change
- for most zones now, so it doesn't matter too much. */
- if (year == YEAR_MINIMUM)
- year = 1601;
-
- /* We just use 9999 here, so we keep to 4 characters. But this should only
- be needed when debugging - it shouldn't be needed in the VTIMEZONEs. */
- if (year == YEAR_MAXIMUM) {
- fprintf (stderr, "format_time: YEAR_MAXIMUM used\n");
- year = 9999;
- }
-
- hour = time / 3600;
- minute = (time % 3600) / 60;
- second = time % 60;
-
- sprintf (buffer, "%04i%02i%02iT%02i%02i%02i",
- year, month + 1, day, hour, minute, second);
-
- return buffer;
-}
-
-
-/* Outlook doesn't support 6-digit values, i.e. including the seconds, so
- we round to the nearest minute. No current offsets use the seconds value,
- so we aren't losing much. */
-static char*
-format_tz_offset (int tz_offset,
- gboolean round_seconds)
-{
- static char buffer[128];
- char *sign = "+";
- int hours, minutes, seconds;
-
- if (tz_offset < 0) {
- tz_offset = -tz_offset;
- sign = "-";
- }
-
- if (round_seconds)
- tz_offset += 30;
-
- hours = tz_offset / 3600;
- minutes = (tz_offset % 3600) / 60;
- seconds = tz_offset % 60;
-
- if (round_seconds)
- seconds = 0;
-
- /* Sanity check. Standard timezone offsets shouldn't be much more than 12
- hours, and daylight saving shouldn't change it by more than a few hours.
- (The maximum offset is 15 hours 56 minutes at present.) */
- if (hours < 0 || hours >= 24 || minutes < 0 || minutes >= 60
- || seconds < 0 || seconds >= 60) {
- fprintf (stderr, "WARNING: Strange timezone offset: H:%i M:%i S:%i\n",
- hours, minutes, seconds);
- }
-
- if (seconds == 0)
- sprintf (buffer, "%s%02i%02i", sign, hours, minutes);
- else
- sprintf (buffer, "%s%02i%02i%02i", sign, hours, minutes, seconds);
-
- return buffer;
-}
-
-
-static gboolean
-output_rrule (char *rrule_buffer,
- int month,
- DayCode day_code,
- int day_number,
- int day_weekday,
- int day_offset,
- char *until)
-{
- char buffer[1024], buffer2[1024];
-
- buffer[0] = '\0';
-
- if (day_offset > 1 || day_offset < -1) {
- fprintf (stderr, "Invalid day_offset: %i\n", day_offset);
- exit (0);
- }
-
- /* If the DTSTART time was moved to another day when converting to local
- time, we need to adjust the RRULE accordingly. e.g. If the original RRULE
- was on the 19th of the month, but DTSTART was moved 1 day forward, then
- we output the 20th of the month instead. */
- if (day_offset == 1) {
- if (day_code != DAY_LAST_WEEKDAY)
- day_number++;
- day_weekday = (day_weekday + 1) % 7;
-
- /* Check we don't use February 29th. */
- if (month == 1 && day_number > 28) {
- fprintf (stderr, "Can't format RRULE - out of bounds. Month: %i Day number: %i\n", month + 1, day_number);
- exit (0);
- }
-
- /* If we go past the end of the month, move to the next month. */
- if (day_code != DAY_LAST_WEEKDAY && day_number > DaysInMonth[month]) {
- month++;
- day_number = 1;
- }
-
- } else if (day_offset == -1) {
- if (day_code != DAY_LAST_WEEKDAY)
- day_number--;
- day_weekday = (day_weekday + 6) % 7;
-
- if (day_code != DAY_LAST_WEEKDAY && day_number < 1)
- fprintf (stderr, "Month: %i Day number: %i\n", month + 1, day_number);
- }
-
- switch (day_code) {
- case DAY_SIMPLE:
- /* Outlook (2000) will not parse the simple YEARLY RRULEs in VTIMEZONEs,
- or BYMONTHDAY, or BYYEARDAY, which makes this option difficult!
- Currently we use something like BYDAY=1SU, which will be incorrect
- at times. This only affects Asia/Baghdad, Asia/Gaza, Asia/Jerusalem &
- Asia/Damascus at present (and Jerusalem doesn't have specific rules
- at the moment anyway, so that isn't a big loss). */
- if (!VzicPureOutput) {
- if (day_number < 8) {
- printf ("WARNING: %s: Outputting BYDAY=1SU instead of BYMONTHDAY=1-7 for Outlook compatability\n", CurrentZoneName);
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=1SU",
- month + 1);
- } else if (day_number < 15) {
- printf ("WARNING: %s: Outputting BYDAY=2SU instead of BYMONTHDAY=8-14 for Outlook compatability\n", CurrentZoneName);
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=2SU",
- month + 1);
- } else if (day_number < 22) {
- printf ("WARNING: %s: Outputting BYDAY=3SU instead of BYMONTHDAY=15-21 for Outlook compatability\n", CurrentZoneName);
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=3SU",
- month + 1);
- } else {
- printf ("ERROR: %s: Couldn't output RRULE (day=%i) compatible with Outlook\n", CurrentZoneName, day_number);
- exit (1);
- }
- } else {
- sprintf (buffer, "RRULE:FREQ=YEARLY");
- }
- break;
-
- case DAY_WEEKDAY_ON_OR_AFTER:
- if (day_number > DaysInMonth[month] - 6) {
- /* This isn't actually needed at present. */
-#if 0
- fprintf (stderr, "DAY_WEEKDAY_ON_OR_AFTER: %i %i\n", day_number,
- month + 1);
-#endif
-
- if (!VzicPureOutput) {
- printf ("ERROR: %s: Couldn't output RRULE (day>=x) compatible with Outlook\n", CurrentZoneName);
- exit (1);
- } else {
- /* We do 6 days at the end of this month, and 1 at the start of the
- next. We can't do this if we want Outlook compatability, as it
- needs BYMONTHDAY, which Outlook doesn't support. */
- sprintf (buffer,
- "RRULE:FREQ=YEARLY;BYMONTH=%i;BYMONTHDAY=%i,%i,%i,%i,%i,%i;BYDAY=%s",
- month + 1,
- day_number, day_number + 1, day_number + 2, day_number + 3,
- day_number + 4, day_number + 5,
- WeekDays[day_weekday]);
-
- sprintf (buffer2,
- "RRULE:FREQ=YEARLY;BYMONTH=%i;BYMONTHDAY=1;BYDAY=%s",
- (month + 1) % 12 + 1,
- WeekDays[day_weekday]);
-
- sprintf (rrule_buffer, "%s%s\n%s%s\n",
- buffer, until, buffer2, until);
-
- return TRUE;
- }
- }
-
- if (!output_rrule_2 (buffer, month, day_number, day_weekday))
- return FALSE;
-
- break;
-
- case DAY_WEEKDAY_ON_OR_BEFORE:
- if (day_number < 7) {
- /* FIXME: This is unimplemented, but it isn't needed at present anway. */
- fprintf (stderr, "DAY_WEEKDAY_ON_OR_BEFORE: %i. Unimplemented. Exiting...\n", day_number);
- exit (0);
- }
-
- if (!output_rrule_2 (buffer, month, day_number - 6, day_weekday))
- return FALSE;
-
- break;
-
- case DAY_LAST_WEEKDAY:
- if (day_offset == 1) {
- if (month == 1) {
- fprintf (stderr, "DAY_LAST_WEEKDAY - day moved, in February - can't fix\n");
- exit (0);
- }
-
- /* This is only used once at present, for Africa/Cairo. */
-#if 0
- fprintf (stderr, "DAY_LAST_WEEKDAY - day moved\n");
-#endif
-
- if (!VzicPureOutput) {
- printf ("WARNING: %s: Modifying RRULE (last weekday) for Outlook compatability\n", CurrentZoneName);
- sprintf (buffer,
- "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=-1%s",
- month + 1, WeekDays[day_weekday]);
- printf (" Outputting: %s\n", buffer);
- } else {
- /* We do 6 days at the end of this month, and 1 at the start of the
- next. We can't do this if we want Outlook compatability, as it needs
- BYMONTHDAY, which Outlook doesn't support. */
- day_number = DaysInMonth[month];
- sprintf (buffer,
- "RRULE:FREQ=YEARLY;BYMONTH=%i;BYMONTHDAY=%i,%i,%i,%i,%i,%i;BYDAY=%s",
- month + 1,
- day_number - 5, day_number - 4, day_number - 3,
- day_number - 2, day_number - 1, day_number,
- WeekDays[day_weekday]);
-
- sprintf (buffer2,
- "RRULE:FREQ=YEARLY;BYMONTH=%i;BYMONTHDAY=1;BYDAY=%s",
- (month + 1) % 12 + 1,
- WeekDays[day_weekday]);
-
- sprintf (rrule_buffer, "%s%s\n%s%s\n",
- buffer, until, buffer2, until);
-
- return TRUE;
- }
-
- } else if (day_offset == -1) {
- /* We do 7 days 1 day before the end of this month. */
- day_number = DaysInMonth[month];
-
- if (!output_rrule_2 (buffer, month, day_number - 7, day_weekday))
- return FALSE;
-
- sprintf (rrule_buffer, "%s%s\n", buffer, until);
- return TRUE;
- }
-
- sprintf (buffer,
- "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=-1%s",
- month + 1, WeekDays[day_weekday]);
- break;
-
- default:
- fprintf (stderr, "Invalid day code\n");
- exit (1);
- }
-
- sprintf (rrule_buffer, "%s%s\n", buffer, until);
- return TRUE;
-}
-
-
-/* This tries to convert a RRULE like 'BYMONTHDAY=8,9,10,11,12,13,14;BYDAY=FR'
- into 'BYDAY=2FR'. We need this since Outlook doesn't accept BYMONTHDAY.
- It returns FALSE if conversion is not possible. */
-static gboolean
-output_rrule_2 (char *buffer,
- int month,
- int day_number,
- int day_weekday)
-{
-
- if (day_number == 1) {
- /* Convert it to a BYDAY=1SU type of RRULE. */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=1%s",
- month + 1, WeekDays[day_weekday]);
-
- } else if (day_number == 8) {
- /* Convert it to a BYDAY=2SU type of RRULE. */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=2%s",
- month + 1, WeekDays[day_weekday]);
-
- } else if (day_number == 15) {
- /* Convert it to a BYDAY=3SU type of RRULE. */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=3%s",
- month + 1, WeekDays[day_weekday]);
-
- } else if (day_number == 22) {
- /* Convert it to a BYDAY=4SU type of RRULE. (Currently not used.) */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=4%s",
- month + 1, WeekDays[day_weekday]);
-
- } else if (month != 1 && day_number == DaysInMonth[month] - 6) {
- /* Convert it to a BYDAY=-1SU type of RRULE. (But never for February.) */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=-1%s",
- month + 1, WeekDays[day_weekday]);
-
- } else {
- /* Can't convert to a correct RRULE. If we want Outlook compatability we
- have to use a slightly incorrect RRULE, so the time change will be 1
- week out every 7 or so years. Alternatively we could possibly move the
- change by an hour or so so we would always be 1 or 2 hours out, but
- never 1 week out. Yes, that sounds a better idea. */
- if (!VzicPureOutput) {
- printf ("WARNING: %s: Modifying RRULE to be compatible with Outlook (day >= %i, month = %i)\n", CurrentZoneName, day_number, month + 1);
-
- if (day_number == 2) {
- /* Convert it to a BYDAY=1SU type of RRULE.
- This is needed for Asia/Karachi. */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=1%s",
- month + 1, WeekDays[day_weekday]);
- } else if (day_number == 9) {
- /* Convert it to a BYDAY=2SU type of RRULE.
- This is needed for Antarctica/Palmer & America/Santiago. */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=2%s",
- month + 1, WeekDays[day_weekday]);
- } else if (month != 1 && day_number == DaysInMonth[month] - 7) {
- /* Convert it to a BYDAY=-1SU type of RRULE. (But never for February.)
- This is needed for America/Godthab. */
- sprintf (buffer, "RRULE:FREQ=YEARLY;BYMONTH=%i;BYDAY=-1%s",
- month + 1, WeekDays[day_weekday]);
- } else {
- printf ("ERROR: %s: Couldn't modify RRULE to be compatible with Outlook (day >= %i, month = %i)\n", CurrentZoneName, day_number, month + 1);
- exit (1);
- }
-
- } else {
- sprintf (buffer,
- "RRULE:FREQ=YEARLY;BYMONTH=%i;BYMONTHDAY=%i,%i,%i,%i,%i,%i,%i;BYDAY=%s",
- month + 1,
- day_number, day_number + 1, day_number + 2, day_number + 3,
- day_number + 4, day_number + 5, day_number + 6,
- WeekDays[day_weekday]);
- }
- }
-
- return TRUE;
-}
-
-
-static char*
-format_vzictime (VzicTime *vzictime)
-{
- static char buffer[1024];
-
- sprintf (buffer, "%s %2i %s %s %i %i %s",
- dump_year (vzictime->year), vzictime->month + 1,
- dump_day_coded (vzictime->day_code, vzictime->day_number,
- vzictime->day_weekday),
- dump_time (vzictime->time_seconds, vzictime->time_code, TRUE),
- vzictime->stdoff, vzictime->walloff,
- vzictime->is_infinite ? "INFINITE" : "");
-
- return buffer;
-}
-
-
-static void
-dump_changes (FILE *fp,
- char *zone_name,
- GArray *changes)
-{
- VzicTime *vzictime, *vzictime2 = NULL;
- int i, year_offset, year;
-
- for (i = 0; i < changes->len; i++) {
- vzictime = &g_array_index (changes, VzicTime, i);
-
- if (vzictime->year > MAX_CHANGES_YEAR)
- return;
-
- dump_change (fp, zone_name, vzictime, vzictime->year);
- }
-
- if (changes->len < 2)
- return;
-
- /* Now see if the changes array ends with a pair of recurring changes. */
- vzictime = &g_array_index (changes, VzicTime, changes->len - 2);
- vzictime2 = &g_array_index (changes, VzicTime, changes->len - 1);
- if (!vzictime->is_infinite || !vzictime2->is_infinite)
- return;
-
- year_offset = 1;
- for (;;) {
- year = vzictime->year + year_offset;
- if (year > MAX_CHANGES_YEAR)
- break;
- dump_change (fp, zone_name, vzictime, year);
-
- year = vzictime2->year + year_offset;
- if (year > MAX_CHANGES_YEAR)
- break;
- dump_change (fp, zone_name, vzictime2, year);
-
- year_offset++;
- }
-}
-
-
-static void
-dump_change (FILE *fp,
- char *zone_name,
- VzicTime *vzictime,
- int year)
-{
- int hour, minute, second;
- VzicTime tmp_vzictime;
- static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- /* Output format is:
-
- Zone-Name [tab] Date [tab] Time [tab] UTC-Offset
-
- The Date and Time fields specify the time change in UTC.
-
- The UTC Offset is for local (wall-clock) time. It is the amount of time
- to add to UTC to get local time.
- */
-
- fprintf (fp, "%s\t", zone_name);
-
- if (year == YEAR_MINIMUM) {
- fprintf (fp, " 1 Jan 0001\t 0:00:00", zone_name);
- } else if (year == YEAR_MAXIMUM) {
- fprintf (stderr, "Maximum year found in change time\n");
- exit (1);
- } else {
- tmp_vzictime = *vzictime;
- tmp_vzictime.year = year;
- calculate_actual_time (&tmp_vzictime, TIME_UNIVERSAL,
- vzictime->prev_stdoff, vzictime->prev_walloff);
-
- hour = tmp_vzictime.time_seconds / 3600;
- minute = (tmp_vzictime.time_seconds % 3600) / 60;
- second = tmp_vzictime.time_seconds % 60;
-
- fprintf (fp, "%2i %s %04i\t%2i:%02i:%02i",
- tmp_vzictime.day_number, months[tmp_vzictime.month],
- tmp_vzictime.year, hour, minute, second);
- }
-
- fprintf (fp, "\t%s", format_tz_offset (vzictime->walloff, FALSE));
-
- fprintf (fp, "\n");
-}
-
-
-void
-ensure_directory_exists (char *directory)
-{
- struct stat filestat;
-
- if (stat (directory, &filestat) != 0) {
- /* If the directory doesn't exist, try to create it. */
- if (errno == ENOENT) {
- if (mkdir (directory, 0777) != 0) {
- fprintf (stderr, "Can't create directory: %s\n", directory);
- exit (1);
- }
- } else {
- fprintf (stderr, "Error calling stat() on directory: %s\n", directory);
- exit (1);
- }
- } else if (!S_ISDIR (filestat.st_mode)) {
- fprintf (stderr, "Can't create directory, already exists: %s\n",
- directory);
- exit (1);
- }
-}
-
-
-static void
-expand_tzid_prefix (void)
-{
- char *src, *dest;
- char date_buf[16];
- char ch1, ch2;
- time_t t;
- struct tm *tm;
-
- /* Get today's date as a string in the format "YYYYMMDD". */
- t = time (NULL);
- tm = localtime (&t);
- sprintf (date_buf, "%4i%02i%02i", tm->tm_year + 1900,
- tm->tm_mon + 1, tm->tm_mday);
-
- src = TZIDPrefix;
- dest = TZIDPrefixExpanded;
-
- while (ch1 = *src++) {
-
- /* Look for a '%'. */
- if (ch1 == '%') {
- ch2 = *src++;
-
- if (ch2 == 'D') {
- /* '%D' gets expanded into the date string. */
- strcpy (dest, date_buf);
- dest += strlen (dest);
- } else if (ch2 == '%') {
- /* '%%' gets converted into one '%'. */
- *dest++ = '%';
- } else {
- /* Anything else is output as is. */
- *dest++ = '%';
- *dest++ = ch2;
- }
- } else {
- *dest++ = ch1;
- }
- }
-
-#if 0
- printf ("TZID : %s\n", TZIDPrefix);
- printf ("Expanded: %s\n", TZIDPrefixExpanded);
-#endif
-}
diff --git a/libkcal/libical/vzic-1.3/vzic-output.h b/libkcal/libical/vzic-1.3/vzic-output.h
deleted file mode 100644
index 1e2df9f80..000000000
--- a/libkcal/libical/vzic-1.3/vzic-output.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef _VZIC_OUTPUT_H_
-#define _VZIC_OUTPUT_H_
-
-#include <glib.h>
-
-void output_vtimezone_files (char *directory,
- GArray *zone_data,
- GHashTable *rule_data,
- GHashTable *link_data,
- int max_until_year);
-
-void ensure_directory_exists (char *directory);
-
-#endif /* _VZIC_OUTPUT_H_ */
diff --git a/libkcal/libical/vzic-1.3/vzic-parse.c b/libkcal/libical/vzic-1.3/vzic-parse.c
deleted file mode 100644
index aa50ff265..000000000
--- a/libkcal/libical/vzic-1.3/vzic-parse.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "vzic.h"
-#include "vzic-parse.h"
-
-/* This is the maximum line length we allow. */
-#define MAX_LINE_LEN 1024
-
-/* The maximum number of fields on a line. */
-#define MAX_FIELDS 12
-
-
-typedef enum
-{
- ZONE_ID = 0, /* The 'Zone' at the start of the line. */
- ZONE_NAME = 1,
- ZONE_GMTOFF = 2,
- ZONE_RULES_SAVE = 3,
- ZONE_FORMAT = 4,
- ZONE_UNTIL_YEAR = 5,
- ZONE_UNTIL_MONTH = 6,
- ZONE_UNTIL_DAY = 7,
- ZONE_UNTIL_TIME = 8
-} ZoneFieldNumber;
-
-
-typedef enum
-{
- RULE_ID = 0, /* The 'Rule' at the start of the line. */
- RULE_NAME = 1,
- RULE_FROM = 2,
- RULE_TO = 3,
- RULE_TYPE = 4,
- RULE_IN = 5,
- RULE_ON = 6,
- RULE_AT = 7,
- RULE_SAVE = 8,
- RULE_LETTER_S = 9
-} RuleFieldNumber;
-
-
-typedef enum
-{
- LINK_ID = 0, /* The 'Link' at the start of the line. */
- LINK_FROM = 1,
- LINK_TO = 2
-} LinkFieldNumber;
-
-
-/* This struct contains information used while parsing the files, and is
- passed to most parsing functions. */
-typedef struct _ParsingData ParsingData;
-struct _ParsingData
-{
- /* This is the line being parsed. buffer is a copy that we break into fields
- and sub-fields as it is parsed. */
- char line[MAX_LINE_LEN];
- char buffer[MAX_LINE_LEN];
-
- /* These are pointers to the start of each field in buffer. */
- char *fields[MAX_FIELDS];
- int num_fields;
-
- /* These are just for producing error messages. */
- char *filename;
- int line_number;
-
-
- /* This is an array of ZoneData structs, 1 for each timezone read. */
- GArray *zone_data;
-
- /* This is a hash table of arrays of RuleData structs. As each Rule line is
- read in, a new RuleData struct is filled in and appended to the
- appropriate GArray in the hash table. */
- GHashTable *rule_data;
-
- /* A hash containing data on the Link lines. The keys are the timezones
- where the link is from (i.e. the timezone we will be outputting anyway)
- and the data is a GList of timezones to link to (where we will copy the
- timezone data to). */
- GHashTable *link_data;
-
- int max_until_year;
-};
-
-
-/*
- * Parsing functions, used when reading the Olson timezone data file.
- */
-static void parse_fields (ParsingData *data);
-static gboolean parse_zone_line (ParsingData *data);
-static gboolean parse_zone_continuation_line (ParsingData *data);
-static gboolean parse_zone_common (ParsingData *data,
- int offset);
-static void parse_rule_line (ParsingData *data);
-static void parse_link_line (ParsingData *data);
-
-static int parse_year (ParsingData *data,
- char *field,
- gboolean accept_only,
- int only_value);
-static int parse_month (ParsingData *data,
- char *field);
-static DayCode parse_day (ParsingData *data,
- char *field,
- int *day,
- int *weekday);
-static int parse_weekday (ParsingData *data,
- char *field);
-static int parse_time (ParsingData *data,
- char *field,
- TimeCode *time_code);
-static int parse_number (ParsingData *data,
- char **num);
-static int parse_rules_save (ParsingData *data,
- char *field,
- char **rules);
-
-static void parse_coord (char *coord,
- int len,
- int *result);
-
-void
-parse_olson_file (char *filename,
- GArray **zone_data,
- GHashTable **rule_data,
- GHashTable **link_data,
- int *max_until_year)
-{
- ParsingData data;
- FILE *fp;
- int zone_continues = 0;
-
- *zone_data = g_array_new (FALSE, FALSE, sizeof (ZoneData));
- *rule_data = g_hash_table_new (g_str_hash, g_str_equal);
- *link_data = g_hash_table_new (g_str_hash, g_str_equal);
-
- fp = fopen (filename, "r");
- if (!fp) {
- fprintf (stderr, "Couldn't open file: %s\n", filename);
- exit (1);
- }
-
- data.filename = filename;
- data.zone_data = *zone_data;
- data.rule_data = *rule_data;
- data.link_data = *link_data;
- data.max_until_year = 0;
-
- for (data.line_number = 0; ; data.line_number++) {
- if (fgets (data.line, sizeof (data.line), fp) != data.line)
- break;
-
- strcpy (data.buffer, data.line);
-
- parse_fields (&data);
- if (data.num_fields == 0)
- continue;
-
- if (zone_continues) {
- zone_continues = parse_zone_continuation_line (&data);
- } else if (!strcmp (data.fields[0], "Zone")) {
- zone_continues = parse_zone_line (&data);
- } else if (!strcmp (data.fields[0], "Rule")) {
- parse_rule_line (&data);
- } else if (!strcmp (data.fields[0], "Link")) {
- parse_link_line (&data);
- } else if (!strcmp (data.fields[0], "Leap")) {
- /* We don't care about Leap lines. */
- } else {
- fprintf (stderr, "%s:%i: Invalid line.\n%s\n", filename,
- data.line_number, data.line);
- exit (1);
- }
- }
-
- if (ferror (fp)) {
- fprintf (stderr, "Error reading file: %s\n", filename);
- exit (1);
- }
-
- if (zone_continues) {
- fprintf (stderr, "%s:%i: Zone continuation line expected.\n%s\n",
- filename, data.line_number, data.line);
- exit (1);
- }
-
- fclose (fp);
-
-#if 0
- printf ("Max UNTIL year: %i\n", data.max_until_year);
-#endif
- *max_until_year = data.max_until_year;
-}
-
-
-/* Converts the line into fields. */
-static void
-parse_fields (ParsingData *data)
-{
- int i;
- char *p, *s, ch;
-
- /* Reset all fields to NULL. */
- for (i = 0; i < MAX_FIELDS; i++)
- data->fields[i] = 0;
-
- data->num_fields = 0;
- p = data->buffer;
-
- for (;;) {
- /* Skip whitespace. */
- while (isspace (*p))
- p++;
-
- /* See if we have reached the end of the line or a comment. */
- if (*p == '\0' || *p == '#')
- break;
-
- /* We must have another field, so save the start position. */
- data->fields[data->num_fields++] = p;
-
- /* Now find the end of the field. If the field contains '"' characters
- they are removed and we have to move the rest of the chars back. */
- s = p;
- for (;;) {
- ch = *p;
- if (ch == '\0' || ch == '#') {
- /* Don't move p on since this is the end of the line. */
- *s = '\0';
- break;
- } else if (isspace (ch)) {
- *s = '\0';
- p++;
- break;
- } else if (ch == '"') {
- p++;
- for (;;) {
- ch = *p;
- if (ch == '\0') {
- fprintf (stderr,
- "%s:%i: Closing quote character ('\"') missing.\n%s\n",
- data->filename, data->line_number, data->line);
- exit (1);
- } else if (ch == '"') {
- p++;
- break;
- } else {
- *s++ = ch;
- }
- p++;
- }
- } else {
- *s++ = ch;
- }
- p++;
- }
- }
-
-#if 0
- printf ("%i fields: ", data->num_fields);
- for (i = 0; i < data->num_fields; i++)
- printf ("'%s' ", data->fields[i]);
- printf ("\n");
-#endif
-}
-
-
-static gboolean
-parse_zone_line (ParsingData *data)
-{
- ZoneData zone;
-
- /* All 5 fields up to FORMAT must be present. */
- if (data->num_fields < 5 || data->num_fields > 9) {
- fprintf (stderr, "%s:%i: Invalid Zone line - %i fields.\n%s\n",
- data->filename, data->line_number, data->num_fields,
- data->line);
- exit (1);
- }
-
- zone.zone_name = g_strdup (data->fields[ZONE_NAME]);
- zone.zone_line_data = g_array_new (FALSE, FALSE, sizeof (ZoneLineData));
-
- g_array_append_val (data->zone_data, zone);
-
- return parse_zone_common (data, 0);
-}
-
-
-static gboolean
-parse_zone_continuation_line (ParsingData *data)
-{
- /* All 3 fields up to FORMAT must be present. */
- if (data->num_fields < 3 || data->num_fields > 7) {
- fprintf (stderr,
- "%s:%i: Invalid Zone continuation line - %i fields.\n%s\n",
- data->filename, data->line_number, data->num_fields,
- data->line);
- exit (1);
- }
-
- return parse_zone_common (data, -2);
-}
-
-
-static gboolean
-parse_zone_common (ParsingData *data,
- int offset)
-{
- ZoneData *zone;
- ZoneLineData zone_line;
- TimeCode time_code;
-
- zone_line.stdoff_seconds = parse_time (data,
- data->fields[ZONE_GMTOFF + offset],
- &time_code);
- zone_line.save_seconds = parse_rules_save (data,
- data->fields[ZONE_RULES_SAVE + offset],
- &zone_line.rules);
-
- if (!VzicPureOutput) {
- /* We round the UTC offsets to the nearest minute, to be compatible with
- Outlook. This also works with -ve numbers, I think.
- -56 % 60 = -59. -61 % 60 = -1. */
- if (zone_line.stdoff_seconds >= 0)
- zone_line.stdoff_seconds += 30;
- else
- zone_line.stdoff_seconds -= 29;
- zone_line.stdoff_seconds -= zone_line.stdoff_seconds % 60;
-
- if (zone_line.save_seconds >= 0)
- zone_line.save_seconds += 30;
- else
- zone_line.save_seconds -= 29;
- zone_line.save_seconds -= zone_line.save_seconds % 60;
- }
-
- zone_line.format = g_strdup (data->fields[ZONE_FORMAT + offset]);
-
- if (data->num_fields - offset >= 6) {
- zone_line.until_set = TRUE;
- zone_line.until_year = parse_year (data,
- data->fields[ZONE_UNTIL_YEAR + offset],
- FALSE, 0);
- zone_line.until_month = parse_month (data,
- data->fields[ZONE_UNTIL_MONTH + offset]);
- zone_line.until_day_code = parse_day (data,
- data->fields[ZONE_UNTIL_DAY + offset],
- &zone_line.until_day_number,
- &zone_line.until_day_weekday);
- zone_line.until_time_seconds = parse_time (data,
- data->fields[ZONE_UNTIL_TIME + offset],
- &zone_line.until_time_code);
-
- /* We also want to know the maximum year used in any UNTIL value, so we
- know where to expand all the infinite Rule data to. */
- if (zone_line.until_year != YEAR_MAXIMUM
- && zone_line.until_year != YEAR_MINIMUM)
- data->max_until_year = MAX (data->max_until_year, zone_line.until_year);
-
- } else {
- zone_line.until_set = FALSE;
- }
-
- /* Append it to the last Zone, since that is the one we are currently
- reading. */
- zone = &g_array_index (data->zone_data, ZoneData, data->zone_data->len - 1);
- g_array_append_val (zone->zone_line_data, zone_line);
-
- return zone_line.until_set;
-}
-
-
-static void
-parse_rule_line (ParsingData *data)
-{
- GArray *rule_array;
- RuleData rule;
- char *name;
- TimeCode time_code;
-
- /* All 10 fields must be present. */
- if (data->num_fields != 10) {
- fprintf (stderr, "%s:%i: Invalid Rule line - %i fields.\n%s\n",
- data->filename, data->line_number, data->num_fields,
- data->line);
- exit (1);
- }
-
- name = data->fields[RULE_NAME];
-
- /* Create the GArray and add it to the hash table if it doesn't already
- exist. */
- rule_array = g_hash_table_lookup (data->rule_data, name);
- if (!rule_array) {
- rule_array = g_array_new (FALSE, FALSE, sizeof (RuleData));
- g_hash_table_insert (data->rule_data, g_strdup (name), rule_array);
- }
-
- rule.from_year = parse_year (data, data->fields[RULE_FROM], FALSE, 0);
- if (rule.from_year == YEAR_MAXIMUM) {
- fprintf (stderr, "%s:%i: Invalid Rule FROM value: '%s'\n",
- data->filename, data->line_number, data->fields[RULE_FROM]);
- exit (1);
- }
-
- rule.to_year = parse_year (data, data->fields[RULE_TO], TRUE,
- rule.from_year);
- if (rule.to_year == YEAR_MINIMUM) {
- fprintf (stderr, "%s:%i: Invalid Rule TO value: %s\n",
- data->filename, data->line_number, data->fields[RULE_TO]);
- exit (1);
- }
-
- if (!strcmp (data->fields[RULE_TYPE], "-"))
- rule.type = NULL;
- else {
- printf ("Type: %s\n", data->fields[RULE_TYPE]);
- rule.type = g_strdup (data->fields[RULE_TYPE]);
- }
-
- rule.in_month = parse_month (data, data->fields[RULE_IN]);
- rule.on_day_code = parse_day (data, data->fields[RULE_ON],
- &rule.on_day_number, &rule.on_day_weekday);
- rule.at_time_seconds = parse_time (data, data->fields[RULE_AT],
- &rule.at_time_code);
- rule.save_seconds = parse_time (data, data->fields[RULE_SAVE], &time_code);
-
- if (!strcmp (data->fields[RULE_LETTER_S], "-")) {
- rule.letter_s = NULL;
- } else {
- rule.letter_s = g_strdup (data->fields[RULE_LETTER_S]);
- }
-
- rule.is_shallow_copy = FALSE;
-
- g_array_append_val (rule_array, rule);
-}
-
-
-static void
-parse_link_line (ParsingData *data)
-{
- char *from, *to, *old_from;
- GList *zone_list;
-
- /* We must have 3 fields for a Link. */
- if (data->num_fields != 3) {
- fprintf (stderr, "%s:%i: Invalid Rule line - %i fields.\n%s\n",
- data->filename, data->line_number, data->num_fields,
- data->line);
- exit (1);
- }
-
- from = data->fields[LINK_FROM];
- to = data->fields[LINK_TO];
-
-#if 0
- printf ("LINK FROM: %s\tTO: %s\n", from, to);
-#endif
-
- if (g_hash_table_lookup_extended (data->link_data, from,
- (gpointer) &old_from,
- (gpointer) &zone_list)) {
- from = old_from;
- } else {
- from = g_strdup (from);
- zone_list = NULL;
- }
-
- zone_list = g_list_prepend (zone_list, g_strdup (to));
-
- g_hash_table_insert (data->link_data, from, zone_list);
-}
-
-
-static int
-parse_year (ParsingData *data,
- char *field,
- gboolean accept_only,
- int only_value)
-{
- int len, year = 0;
- char *p;
-
- if (!field) {
- fprintf (stderr, "%s:%i: Missing year.\n%s\n", data->filename,
- data->line_number, data->line);
- exit (1);
- }
-
- len = strlen (field);
- if (accept_only && !strncmp (field, "only", len))
- return only_value;
- if (len >= 2) {
- if (!strncmp (field, "maximum", len))
- return YEAR_MAXIMUM;
- else if (!strncmp (field, "minimum", len))
- return YEAR_MINIMUM;
- }
-
- for (p = field; *p; p++) {
- if (*p < '0' || *p > '9') {
- fprintf (stderr, "%s:%i: Invalid year: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
- }
-
- year = year * 10 + *p - '0';
- }
-
- if (year < 1000 || year > 2037) {
- fprintf (stderr, "%s:%i: Strange year: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
- }
-
- return year;
-}
-
-
-/* Parses a month name, returning 0 (Jan) to 11 (Dec). */
-static int
-parse_month (ParsingData *data,
- char *field)
-{
- static char* months[] = { "january", "february", "march", "april", "may",
- "june", "july", "august", "september", "october",
- "november", "december" };
- char *p;
- int len, i;
-
- /* If the field is missing, it must be the optional UNTIL month, so we return
- 0 for January. */
- if (!field)
- return 0;
-
- for (p = field, len = 0; *p; p++, len++) {
- *p = tolower (*p);
- }
-
- for (i = 0; i < 12; i++) {
- if (!strncmp (field, months[i], len))
- return i;
- }
-
- fprintf (stderr, "%s:%i: Invalid month: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
-}
-
-
-/* Parses a day specifier, returning a code representing the type of match
- together with a day of the month and a weekday number (0=Sun). */
-static DayCode
-parse_day (ParsingData *data,
- char *field,
- int *day,
- int *weekday)
-{
- char *day_part, *p;
- DayCode day_code;
-
- if (!field) {
- *day = 1;
- return DAY_SIMPLE;
- }
-
- *day = *weekday = 0;
-
- if (!strncmp (field, "last", 4)) {
- *weekday = parse_weekday (data, field + 4);
- /* We set the day to the end of the month to make sorting Rules easy. */
- *day = 31;
- return DAY_LAST_WEEKDAY;
- }
-
- day_part = field;
- day_code = DAY_SIMPLE;
-
- for (p = field; *p; p++) {
- if (*p == '<' || *p == '>') {
- if (*(p + 1) == '=') {
- day_code = (*p == '<') ? DAY_WEEKDAY_ON_OR_BEFORE
- : DAY_WEEKDAY_ON_OR_AFTER;
- *p = '\0';
- *weekday = parse_weekday (data, field);
- day_part = p + 2;
- break;
- }
-
- fprintf (stderr, "%s:%i: Invalid day: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
- }
- }
-
- for (p = day_part; *p; p++) {
- if (*p < '0' || *p > '9') {
- fprintf (stderr, "%s:%i: Invalid day: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
- }
-
- *day = *day * 10 + *p - '0';
- }
-
- if (*day < 1 || *day > 31) {
- fprintf (stderr, "%s:%i: Invalid day: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
- }
-
- return day_code;
-}
-
-
-/* Parses a weekday name, returning 0 (Sun) to 6 (Sat). */
-static int
-parse_weekday (ParsingData *data,
- char *field)
-{
- static char* weekdays[] = { "sunday", "monday", "tuesday", "wednesday",
- "thursday", "friday", "saturday" };
- char *p;
- int len, i;
-
- for (p = field, len = 0; *p; p++, len++) {
- *p = tolower (*p);
- }
-
- for (i = 0; i < 7; i++) {
- if (!strncmp (field, weekdays[i], len))
- return i;
- }
-
- fprintf (stderr, "%s:%i: Invalid weekday: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
-}
-
-
-/* Parses a time (hour + minute + second) and returns the result in seconds,
- together with a time code specifying whether it is Wall clock time,
- local standard time, or universal time.
- The time can start with a '-' in which case it will be negative. */
-static int
-parse_time (ParsingData *data,
- char *field,
- TimeCode *time_code)
-{
- char *p;
- int hours = 0, minutes = 0, seconds = 0, result, negative = 0;
-
- if (!field) {
- *time_code = TIME_WALL;
- return 0;
- }
-
- p = field;
- if (*p == '-') {
- p++;
- negative = 1;
- }
-
- hours = parse_number (data, &p);
-
- if (*p == ':') {
- p++;
- minutes = parse_number (data, &p);
-
- if (*p == ':') {
- p++;
- seconds = parse_number (data, &p);
- }
- }
-
- if (hours < 0 || hours > 24
- || minutes < 0 || minutes > 59
- || seconds < 0 || seconds > 59
- || (hours == 24 && (minutes != 0 || seconds != 0))) {
- fprintf (stderr, "%s:%i: Invalid time: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
- }
-
- if (hours == 24) {
- hours = 23;
- minutes = 59;
- seconds = 59;
- }
-
-#if 0
- printf ("Time: %s -> %i:%02i:%02i\n", field, hours, minutes, seconds);
-#endif
-
- result = hours * 3600 + minutes * 60 + seconds;
- if (negative)
- result = -result;
-
- if (*p == '\0') {
- *time_code = TIME_WALL;
- return result;
- }
-
- if (*(p + 1) == '\0') {
- if (*p == 'w') {
- *time_code = TIME_WALL;
- return result;
- } else if (*p == 's') {
- *time_code = TIME_STANDARD;
- return result;
- } else if (*p == 'u' || *p == 'g' || *p == 'z') {
- *time_code = TIME_UNIVERSAL;
- return result;
- }
- }
-
- fprintf (stderr, "%s:%i: Invalid time: %s\n%s\n", data->filename,
- data->line_number, field, data->line);
- exit (1);
-}
-
-
-/* Parses a simple number and returns the result. The pointer argument
- is moved to the first character after the number. */
-static int
-parse_number (ParsingData *data,
- char **num)
-{
- char *p;
- int result;
-
- p = *num;
-
-#if 0
- printf ("In parse_number p:%s\n", p);
-#endif
-
- if (*p < '0' || *p > '9') {
- fprintf (stderr, "%s:%i: Invalid number: %s\n%s\n", data->filename,
- data->line_number, *num, data->line);
- exit (1);
- }
-
- result = *p++ - '0';
-
- while (*p >= '0' && *p <= '9')
- result = result * 10 + *p++ - '0';
-
- *num = p;
- return result;
-}
-
-
-static int
-parse_rules_save (ParsingData *data,
- char *field,
- char **rules)
-{
- TimeCode time_code;
-
- *rules = NULL;
-
- /* Check for just "-". */
- if (field[0] == '-' && field[1] == '\0')
- return 0;
-
- /* Check for a time to add to local standard time. We don't care about a
- time code here, since it is just an offset. */
- if (*field == '-' || (*field >= '0' && *field <= '9'))
- return parse_time (data, field, &time_code);
-
- /* It must be a rules name. */
- *rules = g_strdup (field);
- return 0;
-}
-
-
-
-
-
-GHashTable*
-parse_zone_tab (char *filename)
-{
- GHashTable *zones_hash;
- ZoneDescription *zone_desc;
- FILE *fp;
- char buf[4096];
- gchar **fields, *zone_name, *latitude, *longitude, *p;
-
-
- fp = fopen (filename, "r");
- if (!fp) {
- fprintf (stderr, "Couldn't open file: %s\n", filename);
- exit (1);
- }
-
- zones_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- while (fgets (buf, sizeof(buf), fp)) {
- if (*buf == '#') continue;
-
- g_strchomp (buf);
- fields = g_strsplit (buf,"\t", 4);
-
- if (strlen (fields[0]) != 2) {
- fprintf (stderr, "Invalid zone description line: %s\n", buf);
- exit (1);
- }
-
- zone_name = g_strdup (fields[2]);
-
- zone_desc = g_new (ZoneDescription, 1);
- zone_desc->country_code[0] = fields[0][0];
- zone_desc->country_code[1] = fields[0][1];
- zone_desc->comment = (fields[3] && fields[3][0]) ? g_strdup (fields[3])
- : NULL;
-
- /* Now parse the latitude and longitude. */
- latitude = fields[1];
- longitude = latitude + 1;
- while (*longitude != '+' && *longitude != '-')
- longitude++;
-
- parse_coord (latitude, longitude - latitude, zone_desc->latitude);
- parse_coord (longitude, strlen (longitude), zone_desc->longitude);
-
- g_hash_table_insert (zones_hash, zone_name, zone_desc);
-
-#if 0
- g_print ("Found zone: %s %i %02i %02i,%i %02i %02i\n", zone_name,
- zone_desc->latitude[0], zone_desc->latitude[1],
- zone_desc->latitude[2],
- zone_desc->longitude[0], zone_desc->longitude[1],
- zone_desc->longitude[2]);
-#endif
- }
-
- fclose (fp);
-
- return zones_hash;
-}
-
-
-static void
-parse_coord (char *coord,
- int len,
- int *result)
-{
- int degrees = 0, minutes = 0, seconds = 0;
-
- if (len == 5)
- sscanf (coord + 1, "%2d%2d", &degrees, &minutes);
- else if (len == 6)
- sscanf (coord + 1, "%3d%2d", &degrees, &minutes);
- else if (len == 7)
- sscanf (coord + 1, "%2d%2d%2d", &degrees, &minutes, &seconds);
- else if (len == 8)
- sscanf (coord + 1, "%3d%2d%2d", &degrees, &minutes, &seconds);
- else {
- fprintf (stderr, "Invalid coordinate: %s\n", coord);
- exit (1);
- }
-
- if (coord[0] == '-')
- degrees = -degrees;
-
- result[0] = degrees;
- result[1] = minutes;
- result[2] = seconds;
-}
-
diff --git a/libkcal/libical/vzic-1.3/vzic-parse.h b/libkcal/libical/vzic-1.3/vzic-parse.h
deleted file mode 100644
index c6d7c1be7..000000000
--- a/libkcal/libical/vzic-1.3/vzic-parse.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef _VZIC_PARSE_H_
-#define _VZIC_PARSE_H_
-
-#include <glib.h>
-
-void parse_olson_file (char *filename,
- GArray **zone_data,
- GHashTable **rule_data,
- GHashTable **link_data,
- int *max_until_year);
-
-GHashTable* parse_zone_tab (char *filename);
-
-#endif /* _VZIC_PARSE_H_ */
diff --git a/libkcal/libical/vzic-1.3/vzic-test.pl b/libkcal/libical/vzic-1.3/vzic-test.pl
deleted file mode 100755
index 0bf20ea7f..000000000
--- a/libkcal/libical/vzic-1.3/vzic-test.pl
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/perl -w
-
-#
-# Vzic - a program to convert Olson timezone database files into VZTIMEZONE
-# files compatible with the iCalendar specification (RFC2445).
-#
-# Copyright (C) 2001 Ximian, Inc.
-# Copyright (C) 2003 Damon Chaplin.
-#
-# Author: Damon Chaplin <damon@gnome.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-#
-# This outputs an iCalendar file containing one event in each timezone,
-# as well as all the VTIMEZONEs. We use it for testing compatability with
-# other iCalendar apps like Outlook, by trying to import it there.
-#
-# Currently we have 377 timezones (with tzdata2001d).
-#
-
-# Set this to the toplevel directory of the VTIMEZONE files.
-$ZONEINFO_DIR = "/home/damon/src/zoneinfo";
-
-$output_file = "calendar.ics";
-
-
-# Save this so we can restore it later.
-$input_record_separator = $/;
-
-chdir $ZONEINFO_DIR
- || die "Can't cd to $ZONEINFO_DIR";
-
-# Create the output file, to contain all the VEVENTs & VTIMEZONEs.
-open (OUTPUTFILE, ">$output_file")
- || die "Can't create file: $output_file";
-
-# Output the standard header.
- print OUTPUTFILE <<EOF;
-BEGIN:VCALENDAR
-PRODID:-//Ximian//NONSGML Vzic Test//EN
-VERSION:2.0
-METHOD:PUBLISH
-EOF
-
-$zone_num = 0;
-
-# 365 days in a non-leap year.
-@days_in_month = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
-
-foreach $file (`find -name "*.ics"`) {
- # Get rid of './' at start and whitespace at end.
- $file =~ s/^\.\///;
- $file =~ s/\s+$//;
-
- if ($file eq $output_file) {
- next;
- }
-
-# print "File: $file\n";
-
- # Get the VTIMEZONE data.
- open (ZONEFILE, "$file")
- || die "Can't open file: $ZONEINFO_DIR/$file";
- undef $/;
- $vtimezone = <ZONEFILE>;
- $/ = $input_record_separator;
- close (ZONEFILE);
-
- # Strip the stuff before and after the VTIMEZONE component
- $vtimezone =~ s/^.*BEGIN:VTIMEZONE/BEGIN:VTIMEZONE/s;
- $vtimezone =~ s/END:VTIMEZONE.*$/END:VTIMEZONE\n/s;
-
- print OUTPUTFILE $vtimezone;
-
- # Find the TZID.
- $vtimezone =~ m/TZID:(.*)/;
- $tzid = $1;
-# print "TZID: $tzid\n";
-
- # Find the location.
- $file =~ m/(.*)\.ics/;
- $location = $1;
-# print "LOCATION: $location\n";
-
- # Try to find the current UTC offset that Outlook will use.
- # If there is an RRULE, we look for the first 2 TZOFFSETTO properties,
- # else we just get the first one.
- if ($vtimezone =~ m/RRULE/) {
- $vtimezone =~ m/TZOFFSETTO:([+-]?\d+)/;
- $tzoffsetto = $1;
- $vtimezone =~ m/TZOFFSETFROM:([+-]?\d+)/;
- $tzoffsetfrom = $1;
- $tzoffset = "$tzoffsetfrom/$tzoffsetto";
- } else {
- $vtimezone =~ m/TZOFFSETTO:([+-]?\d+)/s;
- $tzoffset = $1;
- }
-# print "TZOFFSET: $tzoffset\n";
-
- # We put each event on a separate day in 2001 and Jan 2002.
- $day_num = $zone_num;
- if ($day_num >= 365) {
- $year = 2002;
- $day_num -= 365;
- } else {
- $year = 2001;
- }
- $month = -1;
- for ($i = 0; $i < 12; $i++) {
- if ($day_num < $days_in_month[$i]) {
- $month = $i;
- last;
- }
- $day_num -= $days_in_month[$i]
- }
- if ($month == -1) {
- die "month = -1";
- }
-
- $month++;
- $day_num++;
- $date = sprintf ("%i%02i%02i", $year, $month, $day_num);
-# print "Date: $date\n";
-
- # Output a VEVENT using the timezone.
- print OUTPUTFILE <<EOF;
-BEGIN:VEVENT
-UID:vzic-test-${zone_num}
-DTSTAMP:20010101T000000Z
-DTSTART;TZID=${tzid}:${date}T120000
-DTEND;TZID=${tzid}:${date}T130000
-RRULE:FREQ=MONTHLY;BYMONTHDAY=${day_num}
-SUMMARY:($tzoffset) ${location} 12:00-13:00 UTC
-SEQUENCE:1
-END:VEVENT
-EOF
-
- $zone_num++;
-
- # Use this to stop after a certain number.
-# last if ($zone_num == 100);
-}
-
-# Output the standard footer.
- print OUTPUTFILE <<EOF;
-END:VCALENDAR
-EOF
-
-close (OUTPUTFILE);
-
diff --git a/libkcal/libical/vzic-1.3/vzic.c b/libkcal/libical/vzic-1.3/vzic.c
deleted file mode 100644
index 41bfa3b4e..000000000
--- a/libkcal/libical/vzic-1.3/vzic.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "vzic.h"
-#include "vzic-parse.h"
-#include "vzic-dump.h"
-#include "vzic-output.h"
-
-
-/*
- * Global command-line options.
- */
-
-/* By default we output Outlook-compatible output. If --pure is used we
- output pure output, with no changes to be compatible with Outlook. */
-gboolean VzicPureOutput = FALSE;
-
-gboolean VzicDumpOutput = FALSE;
-gboolean VzicDumpChanges = FALSE;
-gboolean VzicDumpZoneNamesAndCoords = TRUE;
-gboolean VzicDumpZoneTranslatableStrings= TRUE;
-gboolean VzicNoRRules = FALSE;
-gboolean VzicNoRDates = FALSE;
-char* VzicOutputDir = "zoneinfo";
-char* VzicUrlPrefix = NULL;
-char* VzicOlsonDir = OLSON_DIR;
-
-GList* VzicTimeZoneNames = NULL;
-
-static void convert_olson_file (char *olson_file);
-
-static void usage (void);
-
-static void free_zone_data (GArray *zone_data);
-static void free_rule_array (gpointer key,
- gpointer value,
- gpointer data);
-static void free_link_data (gpointer key,
- gpointer value,
- gpointer data);
-
-
-int
-main (int argc,
- char *argv[])
-{
- int i;
- char directory[PATHNAME_BUFFER_SIZE];
- char filename[PATHNAME_BUFFER_SIZE];
- GHashTable *zones_hash;
-
- /*
- * Command-Line Option Parsing.
- */
- for (i = 1; i < argc; i++) {
- /*
- * User Options.
- */
-
- /* --pure: Output the perfect VCALENDAR data, which Outlook won't parse
- as it has problems with certain iCalendar constructs. */
- if (!strcmp (argv[i], "--pure"))
- VzicPureOutput = TRUE;
-
- /* --output-dir: specify where to output all the files beneath. The
- default is the current directory. */
- else if (argc > i + 1 && !strcmp (argv[i], "--output-dir"))
- VzicOutputDir = argv[++i];
-
- /* --url-prefix: Used as the base for the TZURL property in each
- VTIMEZONE. The default is to not output TZURL properties. */
- else if (argc > i + 1 && !strcmp (argv[i], "--url-prefix")) {
- int length;
- VzicUrlPrefix = argv[++i];
- /* remove the trailing '/' if there is one */
- length = strlen (VzicUrlPrefix);
- if (VzicUrlPrefix[length - 1] == '/')
- VzicUrlPrefix[length - 1] = '\0';
- }
-
- else if (argc > i + 1 && !strcmp (argv[i], "--olson-dir")) {
- VzicOlsonDir = argv[++i];
- }
-
- /*
- * Debugging Options.
- */
-
- /* --dump: Dump the Rule and Zone data that we parsed from the Olson
- timezone files. This is used to test the parsing code. */
- else if (!strcmp (argv[i], "--dump"))
- VzicDumpOutput = TRUE;
-
- /* --dump-changes: Dumps a list of times when each timezone changed,
- and the new local time offset from UTC. */
- else if (!strcmp (argv[i], "--dump-changes"))
- VzicDumpChanges = TRUE;
-
- /* --no-rrules: Don't output RRULE properties in the VTIMEZONEs. Instead
- it will just output RDATEs for each year up to a certain year. */
- else if (!strcmp (argv[i], "--no-rrules"))
- VzicNoRRules = TRUE;
-
- /* --no-rdates: Don't output multiple RDATEs in a single VTIMEZONE
- component. Instead they will be output separately. */
- else if (!strcmp (argv[i], "--no-rdates"))
- VzicNoRDates = TRUE;
-
- else
- usage ();
- }
-
- /*
- * Create any necessary directories.
- */
- ensure_directory_exists (VzicOutputDir);
-
- if (VzicDumpOutput) {
- /* Create the directories for the dump output, if they don't exist. */
- sprintf (directory, "%s/ZonesVzic", VzicOutputDir);
- ensure_directory_exists (directory);
- sprintf (directory, "%s/RulesVzic", VzicOutputDir);
- ensure_directory_exists (directory);
- }
-
- if (VzicDumpChanges) {
- /* Create the directory for the changes output, if it doesn't exist. */
- sprintf (directory, "%s/ChangesVzic", VzicOutputDir);
- ensure_directory_exists (directory);
- }
-
- /*
- * Convert the Olson timezone files.
- */
- convert_olson_file ("africa");
- convert_olson_file ("antarctica");
- convert_olson_file ("asia");
- convert_olson_file ("australasia");
- convert_olson_file ("europe");
- convert_olson_file ("northamerica");
- convert_olson_file ("southamerica");
-
- /* These are backwards-compatability and weird stuff. */
-#if 0
- convert_olson_file ("backward");
- convert_olson_file ("etcetera");
- convert_olson_file ("leapseconds");
- convert_olson_file ("pacificnew");
- convert_olson_file ("solar87");
- convert_olson_file ("solar88");
- convert_olson_file ("solar89");
-#endif
-
- /* This doesn't really do anything and it messes up vzic-dump.pl so we
- don't bother. */
-#if 0
- convert_olson_file ("factory");
-#endif
-
- /* This is old System V stuff, which we don't currently support since it
- uses 'min' as a Rule FROM value which messes up our algorithm, making
- it too slow and use too much memory. */
-#if 0
- convert_olson_file ("systemv");
-#endif
-
- /* Output the timezone names and coordinates in a zone.tab file, and
- the translatable strings to feed to gettext. */
- if (VzicDumpZoneNamesAndCoords) {
- sprintf (filename, "%s/zone.tab", VzicOlsonDir);
- zones_hash = parse_zone_tab (filename);
-
- dump_time_zone_names (VzicTimeZoneNames, VzicOutputDir, zones_hash);
- }
-
- return 0;
-}
-
-
-static void
-convert_olson_file (char *olson_file)
-{
- char input_filename[PATHNAME_BUFFER_SIZE];
- GArray *zone_data;
- GHashTable *rule_data, *link_data;
- char dump_filename[PATHNAME_BUFFER_SIZE];
- ZoneData *zone;
- int i, max_until_year;
-
- sprintf (input_filename, "%s/%s", VzicOlsonDir, olson_file);
-
- parse_olson_file (input_filename, &zone_data, &rule_data, &link_data,
- &max_until_year);
-
- if (VzicDumpOutput) {
- sprintf (dump_filename, "%s/ZonesVzic/%s", VzicOutputDir, olson_file);
- dump_zone_data (zone_data, dump_filename);
-
- sprintf (dump_filename, "%s/RulesVzic/%s", VzicOutputDir, olson_file);
- dump_rule_data (rule_data, dump_filename);
- }
-
- output_vtimezone_files (VzicOutputDir, zone_data, rule_data, link_data,
- max_until_year);
-
- free_zone_data (zone_data);
- g_hash_table_foreach (rule_data, free_rule_array, NULL);
- g_hash_table_destroy (rule_data);
- g_hash_table_foreach (link_data, free_link_data, NULL);
- g_hash_table_destroy (link_data);
-}
-
-
-static void
-usage (void)
-{
- fprintf (stderr, "Usage: vzic [--dump] [--dump-changes] [--no-rrules] [--no-rdates] [--pure] [--output-dir <directory>] [--url-prefix <url>] [--olson-dir <directory>]\n");
-
- exit (1);
-}
-
-
-
-
-/*
- * Functions to free the data structures.
- */
-
-static void
-free_zone_data (GArray *zone_data)
-{
- ZoneData *zone;
- ZoneLineData *zone_line;
- int i, j;
-
- for (i = 0; i < zone_data->len; i++) {
- zone = &g_array_index (zone_data, ZoneData, i);
-
- g_free (zone->zone_name);
-
- for (j = 0; j < zone->zone_line_data->len; j++) {
- zone_line = &g_array_index (zone->zone_line_data, ZoneLineData, j);
-
- g_free (zone_line->rules);
- g_free (zone_line->format);
- }
-
- g_array_free (zone->zone_line_data, TRUE);
- }
-
- g_array_free (zone_data, TRUE);
-}
-
-
-static void
-free_rule_array (gpointer key,
- gpointer value,
- gpointer data)
-{
- char *name = key;
- GArray *rule_array = value;
- RuleData *rule;
- int i;
-
- for (i = 0; i < rule_array->len; i++) {
- rule = &g_array_index (rule_array, RuleData, i);
-
- if (!rule->is_shallow_copy) {
- g_free (rule->type);
- g_free (rule->letter_s);
- }
- }
-
- g_array_free (rule_array, TRUE);
-
- g_free (name);
-}
-
-
-static void
-free_link_data (gpointer key,
- gpointer value,
- gpointer data)
-{
- GList *link = data;
-
- g_free (key);
-
- while (link) {
- g_free (link->data);
- link = link->next;
- }
-
- g_list_free (data);
-}
-
diff --git a/libkcal/libical/vzic-1.3/vzic.h b/libkcal/libical/vzic-1.3/vzic.h
deleted file mode 100644
index 3d0daf893..000000000
--- a/libkcal/libical/vzic-1.3/vzic.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Vzic - a program to convert Olson timezone database files into VZTIMEZONE
- * files compatible with the iCalendar specification (RFC2445).
- *
- * Copyright (C) 2000-2001 Ximian, Inc.
- * Copyright (C) 2003 Damon Chaplin.
- *
- * Author: Damon Chaplin <damon@gnome.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef _VZIC_H_
-#define _VZIC_H_
-
-#include <glib.h>
-
-
-/*
- * Global command-line options.
- */
-
-/* By default we output Outlook-compatible output. If --pure is used we output
- pure output, with no changes to be compatible with Outlook. */
-extern gboolean VzicPureOutput;
-
-extern gboolean VzicDumpOutput;
-extern gboolean VzicDumpChanges;
-extern gboolean VzicDumpZoneNamesAndCoords;
-extern gboolean VzicDumpZoneTranslatableStrings;
-extern gboolean VzicNoRRules;
-extern gboolean VzicNoRDates;
-extern char* VzicUrlPrefix;
-
-extern GList* VzicTimeZoneNames;
-
-/* The minimum & maximum years we can use. */
-#define YEAR_MINIMUM G_MININT
-#define YEAR_MAXIMUM G_MAXINT
-
-/* The maximum size of any complete pathname. */
-#define PATHNAME_BUFFER_SIZE 1024
-
-/* Days can be expressed either as a simple month day number, 1-31, or a rule
- such as the last Sunday, or the first Monday on or after the 8th. */
-typedef enum
-{
- DAY_SIMPLE,
- DAY_WEEKDAY_ON_OR_AFTER,
- DAY_WEEKDAY_ON_OR_BEFORE,
- DAY_LAST_WEEKDAY
-} DayCode;
-
-
-/* Times can be given either as universal time (UTC), local standard time
- (without daylight-saving adjustments) or wall clock time (local standard
- time plus daylight-saving adjustments, i.e. what you would see on a clock
- on the wall!). */
-typedef enum
-{
- TIME_WALL,
- TIME_STANDARD,
- TIME_UNIVERSAL
-} TimeCode;
-
-
-/* This represents one timezone, e.g. "Africa/Algiers".
- It contains the timezone name, and an array of ZoneLineData structs which
- hold data from each Zone line, including the continuation lines. */
-typedef struct _ZoneData ZoneData;
-struct _ZoneData
-{
- char *zone_name;
-
- /* An array of ZoneLineData, one for each Zone & Zone continuation line
- read in. */
- GArray *zone_line_data;
-};
-
-
-typedef struct _ZoneLineData ZoneLineData;
-struct _ZoneLineData
-{
- /* The amount of time to add to UTC to get local standard time for the
- current time range, in seconds. */
- int stdoff_seconds;
-
- /* Either rules is set to the name of a set of rules, or rules is NULL and
- save is set to the time to add to local standard time to get wall time, in
- seconds. If save is 0 as well, then standard time always applies. */
- char *rules;
- int save_seconds;
-
- /* The format to use for the abbreviated timezone name, e.g. WE%sT.
- The %s is replaced by variable part of the name. (See the letter_s field
- in the RuleData struct below). */
- char *format;
-
- /* TRUE if an UNTIL time is given. */
- gboolean until_set;
-
- /* The UNTIL year, e.g. 2000. */
- int until_year;
-
- /* The UNTIL month 0 (Jan) to 11 (Dec). */
- int until_month;
-
- /* The UNTIL day, either a simple month day number, 1-31, or a rule such as
- the last Sunday, or the first Monday on or after the 8th. */
- DayCode until_day_code;
- int until_day_number; /* 1 to 31. */
- int until_day_weekday; /* 0 (Sun) to 6 (Sat). */
-
- /* The UNTIL time, in seconds from midnight. The code specifies whether the
- time is a wall clock time, local standard time, or universal time. */
- int until_time_seconds;
- TimeCode until_time_code;
-};
-
-
-typedef struct _RuleData RuleData;
-struct _RuleData
-{
- /* The first year that the rule applies to, e.g. 1996.
- Can also be YEAR_MINIMUM. */
- int from_year;
-
- /* The last year that the rule applies to, e.g. 1996.
- Can also be YEAR_MAXIMUM. */
- int to_year;
-
- /* A string used to only match certain years between from and to.
- The rule only applies to the years which match. If type is NULL the rule
- applies to all years betweeen from and to.
- zic uses an external program called yearistype to check the string.
- Currently it is not used in the Olson database. */
- char *type;
-
- /* The month of the rule 0 (Jan) to 11 (Dec). */
- int in_month;
-
- /* The day, either a simple month day number, 1-31, or a rule such as
- the last Sunday, or the first Monday on or after the 8th. */
- DayCode on_day_code;
- int on_day_number;
- int on_day_weekday; /* 0 (Sun) to 6 (Sat). */
-
- /* The time, in seconds from midnight. The code specifies whether the
- time is a wall clock time, local standard time, or universal time. */
- int at_time_seconds;
- TimeCode at_time_code;
-
- /* The amount of time to add to local standard time when the rule is in
- effect, in seconds. If this is not 0 then it must be a daylight-saving
- time. */
- int save_seconds;
-
- /* The letter(s) to use as the variable part in the abbreviated timezone
- name. If this is NULL then no variable part is used. (See the format field
- in the ZoneLineData struct above.) */
- char *letter_s;
-
-
- /* This is set to TRUE if this element is a shallow copy of another one,
- in which case we don't free any of the fields. */
- gboolean is_shallow_copy;
-};
-
-
-typedef struct _ZoneDescription ZoneDescription;
-struct _ZoneDescription
-{
- /* 2-letter ISO 3166 country code. */
- char country_code[2];
-
- /* latitude and longitude in degrees, minutes & seconds. The degrees value
- holds the sign of the entire latitude/longitude. */
- int latitude[3];
- int longitude[3];
-
- char *comment;
-};
-
-#endif /* _VZIC_H_ */