10 #define FRACTION(n,x) ((unsigned)(n)/(x)),((unsigned)(n)%(x))
12 static void show_temperature(FILE *f, temperature_t temp, const char *pre, const char *post)
15 int mcelsius = temp.mkelvin - 273150;
19 mcelsius = - mcelsius;
21 fprintf(f, "%s%s%u.%03u C%s", pre, sign, FRACTION(mcelsius, 1000), post);
25 static void show_depth(FILE *f, depth_t depth, const char *pre, const char *post)
28 fprintf(f, "%s%u.%03u m%s", pre, FRACTION(depth.mm, 1000), post);
31 static void show_duration(FILE *f, duration_t duration, const char *pre, const char *post)
34 fprintf(f, "%s%u:%02u min%s", pre, FRACTION(duration.seconds, 60), post);
37 static void show_pressure(FILE *f, pressure_t pressure, const char *pre, const char *post)
40 fprintf(f, "%s%u.%03u bar%s", pre, FRACTION(pressure.mbar, 1000), post);
44 * We're outputting utf8 in xml.
45 * We need to quote the characters <, >, &.
47 * Nothing else (and if we ever do this using attributes, we'd need to
48 * quote the quotes we use too).
50 static void quote(FILE *f, const char *text)
73 fwrite(text, (p - text - 1), 1, f);
81 static void show_utf8(FILE *f, const char *text, const char *pre, const char *post)
87 while (isspace(*text))
92 while (len && isspace(text[len-1]))
100 static void save_overview(FILE *f, struct dive *dive)
102 show_depth(f, dive->maxdepth, " <maxdepth>", "</maxdepth>\n");
103 show_depth(f, dive->meandepth, " <meandepth>", "</meandepth>\n");
104 show_temperature(f, dive->airtemp, " <airtemp>", "</airtemp>\n");
105 show_temperature(f, dive->watertemp, " <watertemp>", "</airtemp>\n");
106 show_duration(f, dive->duration, " <duration>", "</duration>\n");
107 show_duration(f, dive->surfacetime, " <surfacetime>", "</surfacetime>\n");
108 show_pressure(f, dive->beginning_pressure, " <cylinderstartpressure>", "</cylinderstartpressure>\n");
109 show_pressure(f, dive->end_pressure, " <cylinderendpressure>", "</cylinderendpressure>\n");
110 show_utf8(f, dive->location, " <location>","</location>\n");
111 show_utf8(f, dive->notes, " <notes>","</notes>\n");
114 static void save_gasmix(FILE *f, struct dive *dive)
118 for (i = 0; i < MAX_MIXES; i++) {
119 gasmix_t *mix = dive->gasmix+i;
120 int o2 = mix->o2.permille, he = mix->he.permille;
121 int n2 = 1000 - o2 - he;
123 if (!mix->o2.permille)
125 fprintf(f, " <gasmix o2='%u.%u%%'", FRACTION(o2, 10));
126 if (mix->he.permille)
127 fprintf(f, " he='%u.%u%%'", FRACTION(he, 10));
128 fprintf(f, " n2='%u.%u%%' />\n", FRACTION(n2, 10));
132 static void save_sample(FILE *f, struct sample *sample)
134 fprintf(f, " <sample time='%u:%02u min' depth='%u.%03u m'",
135 FRACTION(sample->time.seconds,60),
136 FRACTION(sample->depth.mm, 1000));
137 show_temperature(f, sample->temperature, " temp='", "'");
138 show_pressure(f, sample->tankpressure, " pressure='", "'");
139 if (sample->tankindex)
140 fprintf(f, " tankindex='%d'", sample->tankindex);
144 static void save_dive(FILE *f, struct dive *dive)
147 struct tm *tm = gmtime(&dive->when);
149 fprintf(f, "<dive date='%04u-%02u-%02u' time='%02u:%02u:%02u'>\n",
150 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
151 tm->tm_hour, tm->tm_min, tm->tm_sec);
152 save_overview(f, dive);
153 save_gasmix(f, dive);
154 for (i = 0; i < dive->samples; i++)
155 save_sample(f, dive->sample+i);
156 fprintf(f, "</dive>\n");
161 void save_dives(const char *filename)
164 FILE *f = fopen(filename, "w");
169 /* Flush any edits of current dives back to the dives! */
170 flush_dive_info_changes();
172 fprintf(f, "<dives>\n<program name='diveclog' version='%d'></program>\n", VERSION);
173 for (i = 0; i < dive_table.nr; i++)
174 save_dive(f, get_dive(i));
175 fprintf(f, "</dives>\n");