2011-09-20 19:40:34 +00:00
|
|
|
/* main.c */
|
2011-08-31 01:40:25 +00:00
|
|
|
#include <stdio.h>
|
2011-09-02 23:40:28 +00:00
|
|
|
#include <string.h>
|
2011-08-31 01:40:25 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include "dive.h"
|
2011-09-05 19:12:58 +00:00
|
|
|
#include "divelist.h"
|
2011-09-20 18:24:15 +00:00
|
|
|
|
2011-09-07 02:07:17 +00:00
|
|
|
struct units output_units;
|
|
|
|
|
2011-09-20 19:40:34 +00:00
|
|
|
/* random helper functions, used here or elsewhere */
|
2011-08-31 01:40:25 +00:00
|
|
|
static int sortfn(const void *_a, const void *_b)
|
|
|
|
{
|
|
|
|
const struct dive *a = *(void **)_a;
|
|
|
|
const struct dive *b = *(void **)_b;
|
|
|
|
|
|
|
|
if (a->when < b->when)
|
|
|
|
return -1;
|
|
|
|
if (a->when > b->when)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-20 19:40:34 +00:00
|
|
|
const char *weekday(int wday)
|
|
|
|
{
|
|
|
|
static const char wday_array[7][4] = {
|
|
|
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
|
|
|
};
|
|
|
|
return wday_array[wday];
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *monthname(int mon)
|
|
|
|
{
|
|
|
|
static const char month_array[12][4] = {
|
|
|
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
2011-09-21 12:44:34 +00:00
|
|
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
|
2011-09-20 19:40:34 +00:00
|
|
|
};
|
|
|
|
return month_array[mon];
|
|
|
|
}
|
|
|
|
|
2011-10-05 15:31:31 +00:00
|
|
|
/*
|
|
|
|
* When adding dives to the dive table, we try to renumber
|
|
|
|
* the new dives based on any old dives in the dive table.
|
|
|
|
*
|
|
|
|
* But we only do it if:
|
|
|
|
*
|
|
|
|
* - the last dive in the old dive table was numbered
|
|
|
|
*
|
|
|
|
* - all the new dives are strictly at the end (so the
|
|
|
|
* "last dive" is at the same location in the dive table
|
|
|
|
* after re-sorting the dives.
|
|
|
|
*
|
|
|
|
* - none of the new dives have any numbers
|
|
|
|
*
|
|
|
|
* This catches the common case of importing new dives from
|
|
|
|
* a dive computer, and gives them proper numbers based on
|
|
|
|
* your old dive list. But it tries to be very conservative
|
|
|
|
* and not give numbers if there is *any* question about
|
|
|
|
* what the numbers should be - in which case you need to do
|
|
|
|
* a manual re-numbering.
|
|
|
|
*/
|
|
|
|
static void try_to_renumber(struct dive *last, int preexisting)
|
|
|
|
{
|
|
|
|
int i, nr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the new dives aren't all strictly at the end,
|
|
|
|
* we're going to expect the user to do a manual
|
|
|
|
* renumbering.
|
|
|
|
*/
|
|
|
|
if (get_dive(preexisting-1) != last)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If any of the new dives already had a number,
|
|
|
|
* we'll have to do a manual renumbering.
|
|
|
|
*/
|
|
|
|
for (i = preexisting; i < dive_table.nr; i++) {
|
|
|
|
struct dive *dive = get_dive(i);
|
|
|
|
if (dive->number)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ok, renumber..
|
|
|
|
*/
|
|
|
|
nr = last->number;
|
|
|
|
for (i = preexisting; i < dive_table.nr; i++) {
|
|
|
|
struct dive *dive = get_dive(i);
|
|
|
|
dive->number = ++nr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-05 21:09:49 +00:00
|
|
|
/*
|
|
|
|
* track whether we switched to importing dives
|
|
|
|
*/
|
|
|
|
static gboolean imported = FALSE;
|
|
|
|
|
2011-08-31 02:48:00 +00:00
|
|
|
/*
|
|
|
|
* This doesn't really report anything at all. We just sort the
|
|
|
|
* dives, the GUI does the reporting
|
|
|
|
*/
|
2012-01-05 16:16:08 +00:00
|
|
|
void report_dives(gboolean is_imported)
|
2011-08-31 01:40:25 +00:00
|
|
|
{
|
2011-09-02 23:40:28 +00:00
|
|
|
int i;
|
2011-10-05 15:31:31 +00:00
|
|
|
int preexisting = dive_table.preexisting;
|
|
|
|
struct dive *last;
|
|
|
|
|
|
|
|
/* This does the right thing for -1: NULL */
|
|
|
|
last = get_dive(preexisting-1);
|
2011-09-02 23:40:28 +00:00
|
|
|
|
2011-08-31 01:40:25 +00:00
|
|
|
qsort(dive_table.dives, dive_table.nr, sizeof(struct dive *), sortfn);
|
2011-09-02 23:40:28 +00:00
|
|
|
|
|
|
|
for (i = 1; i < dive_table.nr; i++) {
|
|
|
|
struct dive **pp = &dive_table.dives[i-1];
|
|
|
|
struct dive *prev = pp[0];
|
|
|
|
struct dive *dive = pp[1];
|
|
|
|
struct dive *merged;
|
|
|
|
|
|
|
|
if (prev->when + prev->duration.seconds < dive->when)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
merged = try_to_merge(prev, dive);
|
|
|
|
if (!merged)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
free(prev);
|
|
|
|
free(dive);
|
|
|
|
*pp = merged;
|
|
|
|
dive_table.nr--;
|
|
|
|
memmove(pp+1, pp+2, sizeof(*pp)*(dive_table.nr - i));
|
|
|
|
|
|
|
|
/* Redo the new 'i'th dive */
|
|
|
|
i--;
|
|
|
|
}
|
2011-10-05 15:06:48 +00:00
|
|
|
|
2012-01-05 16:16:08 +00:00
|
|
|
if (is_imported) {
|
2011-10-05 18:36:15 +00:00
|
|
|
/* Was the previous dive table state numbered? */
|
|
|
|
if (last && last->number)
|
|
|
|
try_to_renumber(last, preexisting);
|
2011-10-05 15:31:31 +00:00
|
|
|
|
2011-10-05 18:36:15 +00:00
|
|
|
/* did we have dives in the table and added more? */
|
|
|
|
if (last && preexisting != dive_table.nr)
|
|
|
|
mark_divelist_changed(TRUE);
|
|
|
|
}
|
2011-10-05 15:31:31 +00:00
|
|
|
dive_table.preexisting = dive_table.nr;
|
2011-10-05 15:06:48 +00:00
|
|
|
dive_list_update_dives();
|
2011-08-31 01:40:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void parse_argument(const char *arg)
|
|
|
|
{
|
|
|
|
const char *p = arg+1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
switch (*p) {
|
|
|
|
case 'v':
|
|
|
|
verbose++;
|
|
|
|
continue;
|
2011-10-05 18:36:15 +00:00
|
|
|
case '-':
|
|
|
|
/* long options with -- */
|
|
|
|
if (strcmp(arg,"--import") == 0) {
|
|
|
|
/* mark the dives so far as the base,
|
|
|
|
* everything after is imported */
|
2011-10-05 21:09:49 +00:00
|
|
|
report_dives(FALSE);
|
|
|
|
imported = TRUE;
|
2011-10-05 18:36:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* fallthrough */
|
2011-10-30 19:56:28 +00:00
|
|
|
case 'p':
|
|
|
|
/* ignore process serial number argument when run as native macosx app */
|
|
|
|
if (strncmp(arg, "-psn_", 5) == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2012-08-26 21:41:05 +00:00
|
|
|
/* fallthrough */
|
2011-08-31 01:40:25 +00:00
|
|
|
default:
|
|
|
|
fprintf(stderr, "Bad argument '%s'\n", arg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
} while (*++p);
|
|
|
|
}
|
|
|
|
|
2011-09-10 00:10:17 +00:00
|
|
|
void update_dive(struct dive *new_dive)
|
|
|
|
{
|
|
|
|
static struct dive *buffered_dive;
|
|
|
|
struct dive *old_dive = buffered_dive;
|
|
|
|
|
|
|
|
if (old_dive) {
|
2011-09-20 17:06:24 +00:00
|
|
|
flush_divelist(old_dive);
|
2011-09-10 00:10:17 +00:00
|
|
|
}
|
|
|
|
if (new_dive) {
|
|
|
|
show_dive_info(new_dive);
|
2012-08-15 22:21:34 +00:00
|
|
|
show_dive_equipment(new_dive, W_IDX_PRIMARY);
|
2011-11-02 16:10:57 +00:00
|
|
|
show_dive_stats(new_dive);
|
2011-09-10 00:10:17 +00:00
|
|
|
}
|
2011-09-11 20:43:37 +00:00
|
|
|
buffered_dive = new_dive;
|
2011-09-10 00:10:17 +00:00
|
|
|
}
|
|
|
|
|
2011-09-20 19:40:34 +00:00
|
|
|
void renumber_dives(int nr)
|
2011-09-11 22:39:46 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < dive_table.nr; i++) {
|
|
|
|
struct dive *dive = dive_table.dives[i];
|
|
|
|
dive->number = nr + i;
|
2011-10-23 15:50:14 +00:00
|
|
|
flush_divelist(dive);
|
2011-09-11 22:39:46 +00:00
|
|
|
}
|
2011-10-05 16:24:52 +00:00
|
|
|
mark_divelist_changed(TRUE);
|
2011-09-11 22:39:46 +00:00
|
|
|
}
|
|
|
|
|
2011-08-31 01:40:25 +00:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int i;
|
2012-09-09 16:06:44 +00:00
|
|
|
gboolean no_filenames = TRUE;
|
2011-08-31 01:40:25 +00:00
|
|
|
|
2011-09-07 02:07:17 +00:00
|
|
|
output_units = SI_units;
|
2011-09-27 17:16:40 +00:00
|
|
|
|
2011-08-31 01:40:25 +00:00
|
|
|
parse_xml_init();
|
|
|
|
|
2011-11-02 00:09:15 +00:00
|
|
|
init_ui(&argc, &argv);
|
2012-08-26 21:41:05 +00:00
|
|
|
|
2011-09-05 20:14:53 +00:00
|
|
|
for (i = 1; i < argc; i++) {
|
|
|
|
const char *a = argv[i];
|
|
|
|
|
|
|
|
if (a[0] == '-') {
|
|
|
|
parse_argument(a);
|
|
|
|
continue;
|
|
|
|
}
|
2012-09-09 16:06:44 +00:00
|
|
|
no_filenames = FALSE;
|
2011-09-05 20:14:53 +00:00
|
|
|
GError *error = NULL;
|
2012-01-26 21:00:45 +00:00
|
|
|
parse_file(a, &error);
|
2012-08-26 21:41:05 +00:00
|
|
|
|
2011-09-05 20:14:53 +00:00
|
|
|
if (error != NULL)
|
|
|
|
{
|
|
|
|
report_error(error);
|
|
|
|
g_error_free(error);
|
|
|
|
error = NULL;
|
|
|
|
}
|
|
|
|
}
|
2012-09-09 16:06:44 +00:00
|
|
|
if (no_filenames) {
|
|
|
|
GError *error = NULL;
|
|
|
|
const char *filename = subsurface_default_filename();
|
|
|
|
parse_file(filename, &error);
|
|
|
|
/* don't report errors - this file may not exist, but make
|
|
|
|
sure we remember this as the filename in use */
|
2012-09-10 19:27:00 +00:00
|
|
|
set_filename(filename, FALSE);
|
2012-09-09 16:06:44 +00:00
|
|
|
}
|
2011-10-05 21:09:49 +00:00
|
|
|
report_dives(imported);
|
2011-08-31 02:48:00 +00:00
|
|
|
|
2011-09-20 19:40:34 +00:00
|
|
|
run_ui();
|
2012-05-02 17:03:48 +00:00
|
|
|
exit_ui();
|
2011-08-31 01:40:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|