summaryrefslogtreecommitdiffstats
path: root/libkcal/libical/vzic-1.3/vzic-dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'libkcal/libical/vzic-1.3/vzic-dump.c')
-rw-r--r--libkcal/libical/vzic-1.3/vzic-dump.c409
1 files changed, 409 insertions, 0 deletions
diff --git a/libkcal/libical/vzic-1.3/vzic-dump.c b/libkcal/libical/vzic-1.3/vzic-dump.c
new file mode 100644
index 000000000..405d7eef6
--- /dev/null
+++ b/libkcal/libical/vzic-1.3/vzic-dump.c
@@ -0,0 +1,409 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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);
+}
+