summaryrefslogtreecommitdiffstats
path: root/libkcal/libical/vzic-1.3/vzic.c
diff options
context:
space:
mode:
Diffstat (limited to 'libkcal/libical/vzic-1.3/vzic.c')
-rw-r--r--libkcal/libical/vzic-1.3/vzic.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/libkcal/libical/vzic-1.3/vzic.c b/libkcal/libical/vzic-1.3/vzic.c
new file mode 100644
index 000000000..1108d8777
--- /dev/null
+++ b/libkcal/libical/vzic-1.3/vzic.c
@@ -0,0 +1,320 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, 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);
+}
+