/* * xlog - GTK+ logging program for amateur radio operators * Copyright (C) 2001-2002 Joop Stakenborg * * This program is free oftware; 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 Library 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. */ /* * editest.c - support for .exp Editest file format (CSV like) * Reports to Stephane Fillod F8CFE */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "logfile.h" #include "types.h" /* * Editest is a french contest logging program. * Files can be generated for 2 kinds of contest. * Number of fields is identical for both. * * For HF: * DATE GMT CALL RST MYRST NR BAND PTS ZONE * For VHF: * DATE GMT CALL RST MYRST LOCATOR BAND PTS KM * * Note: there's no MODE field! */ /* * file fields */ const gint editest_fields[] = { DATE, GMT, CALL, RST, MYRST, LOCATOR, BAND }; const gint editest_widths[] = { 9, 5, 14, 8, 8, 9, 9, 5 }; const gint editest_field_nr = 7; static gint editest_open(LOGDB*); static void editest_close(LOGDB*); static gint editest_create(LOGDB*); static gint editest_qso_append(LOGDB*, const qso_t*); static gint editest_qso_foreach(LOGDB*, gint (*fn)(LOGDB*, qso_t*, gpointer arg), gpointer arg); const struct log_ops editest_ops = { open: editest_open, close: editest_close, create: editest_create, qso_append: editest_qso_append, qso_foreach: editest_qso_foreach, type: TYPE_EDITEST, name: "Editest", extension: ".exp", }; /* * open for read */ gint editest_open(LOGDB *handle) { FILE *fp; fp = fopen(handle->path, "r"); if (!fp) return -1; handle->priv = (gpointer)fp; handle->column_nr = editest_field_nr; memcpy(handle->column_fields, editest_fields, sizeof(editest_fields)); memcpy(handle->column_widths, editest_widths, sizeof(editest_widths)); return 0; } /* * open for write */ gint editest_create(LOGDB *handle) { FILE *fp; fp = fopen(handle->path, "w"); if (!fp) return -1; handle->priv = (gpointer)fp; return 0; } void editest_close(LOGDB *handle) { FILE *fp = (FILE*)handle->priv; fclose(fp); } /* */ gint editest_qso_append(LOGDB *handle, const qso_t *q) { FILE *fp = (FILE *)handle->priv; gchar rst[16], exch[16] = "", my_rst[16], my_exch[16] = ""; gchar date[16], locator[16]; gchar *p; gint rst_len; /* * there's no exchange fields in xlog. However, the exchange information * may be piggybacked by the rst field. eg. "599 35". */ p = strchr(q[RST], ' '); rst_len = p ? p - q[RST] : strlen(q[RST]); strncpy(rst, q[RST], rst_len); rst[rst_len] = '\0'; strncpy(my_rst, q[MYRST], rst_len); my_rst[rst_len] = '\0'; if (strlen(q[RST]) > rst_len) strcpy(exch, q[RST]+rst_len); if (strlen(q[MYRST]) > rst_len) strcpy(my_exch, q[MYRST]+rst_len); //const gint editest_fields[] = { DATE, GMT, CALL, RST, MYRST, LOCATOR, BAND }; if (strlen(q[DATE]) == 11 && q[DATE][2]==' ' && q[DATE][6]==' ') sprintf(date, "%c%c-%02d-%s", q[DATE][0], q[DATE][1], scan_month(q[DATE]+3), q[DATE]+9); if (q[NR] && (!q[LOCATOR] || strlen(q[LOCATOR]) == 0)) sprintf(locator, "%s", q[NR]); else strcpy(locator, q[LOCATOR] ? q[LOCATOR] : ""); /* * .exp CSV-like format * * If there's no locator data, maybe it's a HF log * * We're missing the points and zone/km column, * hence the empty semicolon * * TODO: compute these from location set in the preferences */ fprintf(fp, "%s;%s;%s;%s;%s;%s;%s;%s;%s;;\n", date, q[GMT], q[CALL], rst, exch, my_rst, my_exch, locator, q[BAND]); return 0; } #define MAXROWLEN 120 gint editest_qso_foreach(LOGDB *handle, gint (*fn)(LOGDB*, qso_t*, gpointer arg), gpointer arg) { FILE *fp = (FILE*)handle->priv; gint ret, i; qso_t q[QSO_FIELDS]; gchar *field; gchar buffer[MAXROWLEN]; gint field_cnt = 0; gint concat; gchar *p, *qfield; while (!feof(fp)) { if (!fgets(buffer, MAXROWLEN-1, fp)) break; memset(q, 0, sizeof(q)); field = buffer; concat = 0; field_cnt = 0; for (p = buffer; *p && field_cnt < editest_field_nr; p++) { if (*p == ';') { /* concat rst with exchange number */ if (!concat && (field_cnt == 3 || field_cnt == 4)) { *p = ' '; concat = 1; continue; } concat = 0; *p = '\0'; if (editest_fields[field_cnt] == DATE) { struct tm timestruct; gchar sdate[16]; sscanf(field, "%2i-%2i-%2i", ×truct.tm_mday, ×truct.tm_mon, ×truct.tm_year); if (timestruct.tm_year < 70) timestruct.tm_year += 100; timestruct.tm_mon--; strftime (sdate, 16, "%d %b %Y", ×truct); qfield = g_strdup(sdate); } else qfield = g_strdup(field); q[editest_fields[field_cnt]] = qfield; field = p+1; field_cnt++; } } /* fill in empty fields */ for (i = 0; i