summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-05-20 09:44:55 -0700
committerKeith Packard <keithp@keithp.com>2009-05-20 09:44:55 -0700
commitaa6d87aeb616dd62f0debaded297232022b4f8bd (patch)
tree3fb8b12bcb2796fdcf7ce1dd16c45fd44176937d
parentb730c8bcbce649cdddba935e1112aaae538bc526 (diff)
Make file handling more general so it can be reused.
The log file handling stuff will be useful for saving eeprom data, so pull it out of the real-time log handling code and make a general interface. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--aoview/Makefile3
-rw-r--r--aoview/aoview.glade16
-rw-r--r--aoview/aoview.h29
-rw-r--r--aoview/aoview_file.c230
-rw-r--r--aoview/aoview_log.c152
-rw-r--r--aoview/aoview_main.c2
6 files changed, 285 insertions, 147 deletions
diff --git a/aoview/Makefile b/aoview/Makefile
index a2878b0e..ca636065 100644
--- a/aoview/Makefile
+++ b/aoview/Makefile
@@ -17,7 +17,8 @@ SRC = \
aoview_convert.c \
aoview_log.c \
aoview_table.c \
- aoview_util.c
+ aoview_util.c \
+ aoview_file.c
INC = \
aoview.h
diff --git a/aoview/aoview.glade b/aoview/aoview.glade
index 74485ec5..eb7f108b 100644
--- a/aoview/aoview.glade
+++ b/aoview/aoview.glade
@@ -167,7 +167,7 @@
<widget class="GtkMenu" id="menu5">
<property name="visible">True</property>
<child>
- <widget class="GtkImageMenuItem" id="ao_log_new">
+ <widget class="GtkImageMenuItem" id="log_new">
<property name="label" translatable="yes">_New log</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
@@ -181,12 +181,12 @@
</widget>
</child>
<child>
- <widget class="GtkImageMenuItem" id="ao_log_configure">
+ <widget class="GtkImageMenuItem" id="file_configure">
<property name="label" translatable="yes">_Configure Log</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="use_stock">False</property>
- <signal name="activate" handler="gtk_widget_show" object="log_chooser_dialog" after="yes"/>
+ <signal name="activate" handler="gtk_widget_show" object="file_chooser_dialog" after="yes"/>
<child internal-child="image">
<widget class="GtkImage" id="image4">
<property name="visible">True</property>
@@ -315,7 +315,7 @@
</widget>
</child>
</widget>
- <widget class="GtkFileChooserDialog" id="log_chooser_dialog">
+ <widget class="GtkFileChooserDialog" id="file_chooser_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Configure Log Directory</property>
<property name="type_hint">dialog</property>
@@ -331,13 +331,13 @@
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
- <widget class="GtkButton" id="log_configure_cancel">
+ <widget class="GtkButton" id="file_configure_cancel">
<property name="label" translatable="yes">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
- <signal name="clicked" handler="gtk_widget_hide" object="log_chooser_dialog"/>
+ <signal name="clicked" handler="gtk_widget_hide" object="file_chooser_dialog"/>
</widget>
<packing>
<property name="expand">False</property>
@@ -346,7 +346,7 @@
</packing>
</child>
<child>
- <widget class="GtkButton" id="log_configure_ok">
+ <widget class="GtkButton" id="file_configure_ok">
<property name="label" translatable="yes">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -371,7 +371,7 @@
</widget>
</child>
</widget>
- <widget class="GtkMessageDialog" id="log_fail_dialog">
+ <widget class="GtkMessageDialog" id="file_fail_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Failed to create log</property>
<property name="type_hint">normal</property>
diff --git a/aoview/aoview.h b/aoview/aoview.h
index 4abbde88..7b5f0de5 100644
--- a/aoview/aoview.h
+++ b/aoview/aoview.h
@@ -170,4 +170,33 @@ aoview_table_init(GladeXML *xml);
void
aoview_table_clear(void);
+struct aoview_file;
+
+void
+aoview_file_finish(struct aoview_file *file);
+
+gboolean
+aoview_file_start(struct aoview_file *file);
+
+void
+aoview_file_set_serial(struct aoview_file *file, int serial);
+
+int
+aoview_file_get_serial(struct aoview_file *file);
+
+void
+aoview_file_printf(struct aoview_file *file, char *format, ...);
+
+void
+aoview_file_vprintf(struct aoview_file *file, char *format, va_list ap);
+
+struct aoview_file *
+aoview_file_new(char *ext);
+
+void
+aoview_file_destroy(struct aoview_file *file);
+
+void
+aoview_file_init(GladeXML *xml);
+
#endif /* _AOVIEW_H_ */
diff --git a/aoview/aoview_file.c b/aoview/aoview_file.c
new file mode 100644
index 00000000..d86d5878
--- /dev/null
+++ b/aoview/aoview_file.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 "aoview.h"
+
+static char *aoview_file_dir;
+
+#define ALTOS_DIR_PATH "/apps/aoview/log_dir"
+#define DEFAULT_DIR "AltOS"
+
+struct aoview_file {
+ char *ext;
+ FILE *file;
+ char *name;
+ int failed;
+ int serial;
+ int sequence;
+};
+
+static void
+aoview_file_save_conf(void)
+{
+ GConfClient *gconf_client;
+
+ gconf_client = gconf_client_get_default();
+ if (gconf_client)
+ {
+ gconf_client_set_string(gconf_client,
+ ALTOS_DIR_PATH,
+ aoview_file_dir,
+ NULL);
+ g_object_unref(G_OBJECT(gconf_client));
+ }
+}
+
+static void
+aoview_file_configure(GtkWidget *widget, gpointer data)
+{
+ GtkFileChooser *chooser = data;
+ aoview_file_dir = gtk_file_chooser_get_filename(chooser);
+ aoview_file_save_conf();
+ gtk_widget_hide(GTK_WIDGET(chooser));
+}
+
+void
+aoview_file_finish(struct aoview_file *file)
+{
+ if (file->file) {
+ fclose(file->file);
+ file->file = NULL;
+ free(file->name);
+ file->name = NULL;
+ }
+ file->failed = 0;
+}
+
+static GtkMessageDialog *file_fail_dialog;
+
+static void
+aoview_file_open_failed(char *name)
+{
+ char *utf8_file;
+ utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
+ if (!utf8_file)
+ utf8_file = name;
+ gtk_message_dialog_format_secondary_text(file_fail_dialog,
+ "\"%s\"", utf8_file);
+ if (utf8_file != name)
+ g_free(utf8_file);
+ gtk_widget_show(GTK_WIDGET(file_fail_dialog));
+}
+
+gboolean
+aoview_file_start(struct aoview_file *file)
+{
+ char base[50];
+ struct tm tm;
+ time_t now;
+ char *full;
+ int r;
+
+ if (file->file)
+ return TRUE;
+
+ if (file->failed)
+ return FALSE;
+
+ now = time(NULL);
+ (void) localtime_r(&now, &tm);
+ aoview_mkdir(aoview_file_dir);
+ for (;;) {
+ snprintf(base, sizeof (base), "%04d-%02d-%02d-serial-%03d-flight-%03d.%s",
+ tm.tm_year + 1900,
+ tm.tm_mon + 1,
+ tm.tm_mday,
+ file->serial,
+ file->sequence,
+ file->ext);
+ full = aoview_fullname(aoview_file_dir, base);
+ r = access(full, F_OK);
+ if (r < 0) {
+ file->file = fopen(full, "w");
+ if (!file->file) {
+ aoview_file_open_failed(full);
+ free(full);
+ file->failed = 1;
+ return FALSE;
+ } else {
+ setlinebuf(file->file);
+ file->name = full;
+ return TRUE;
+ }
+ }
+ free(full);
+ file->sequence++;
+ }
+}
+
+void
+aoview_file_vprintf(struct aoview_file *file, char *format, va_list ap)
+{
+ if (!aoview_file_start(file))
+ return;
+ vfprintf(file->file, format, ap);
+}
+
+void
+aoview_file_printf(struct aoview_file *file, char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ aoview_file_vprintf(file, format, ap);
+ va_end(ap);
+}
+
+struct aoview_file *
+aoview_file_new(char *ext)
+{
+ struct aoview_file *file;
+
+ file = calloc (1, sizeof (struct aoview_file));
+ if (!file)
+ return NULL;
+ file->ext = strdup(ext);
+ if (!file->ext) {
+ free(file);
+ return NULL;
+ }
+ return file;
+}
+
+void
+aoview_file_destroy(struct aoview_file *file)
+{
+ if (file->file)
+ fclose(file->file);
+ if (file->name)
+ free(file->name);
+ free(file->ext);
+ free(file);
+}
+
+void
+aoview_file_set_serial(struct aoview_file *file, int serial)
+{
+ if (serial != file->serial)
+ aoview_file_finish(file);
+ file->serial = serial;
+}
+
+int
+aoview_file_get_serial(struct aoview_file *file)
+{
+ return file->serial;
+}
+
+void
+aoview_file_init(GladeXML *xml)
+{
+ GConfClient *gconf_client;
+ char *file_dir = NULL;
+ GtkFileChooser *file_chooser_dialog;
+ GtkWidget *file_configure_ok;
+
+ g_type_init();
+ gconf_client = gconf_client_get_default();
+ if (gconf_client)
+ {
+ file_dir = gconf_client_get_string(gconf_client,
+ ALTOS_DIR_PATH,
+ NULL);
+ g_object_unref(G_OBJECT(gconf_client));
+ }
+ if (!file_dir) {
+ aoview_file_dir = aoview_fullname(getenv("HOME"), DEFAULT_DIR);
+ aoview_file_save_conf();
+ } else {
+ aoview_file_dir = strdup(file_dir);
+ }
+
+ file_chooser_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "file_chooser_dialog"));
+ assert(file_chooser_dialog);
+ gtk_file_chooser_set_filename(file_chooser_dialog, aoview_file_dir);
+
+ file_configure_ok = glade_xml_get_widget(xml, "file_configure_ok");
+ assert(file_configure_ok);
+
+ g_signal_connect(G_OBJECT(file_configure_ok), "clicked",
+ G_CALLBACK(aoview_file_configure),
+ file_chooser_dialog);
+
+
+ file_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "file_fail_dialog"));
+ assert(file_fail_dialog);
+}
diff --git a/aoview/aoview_log.c b/aoview/aoview_log.c
index 0afdb64e..2f2b9560 100644
--- a/aoview/aoview_log.c
+++ b/aoview/aoview_log.c
@@ -17,121 +17,25 @@
#include "aoview.h"
-#define LOG_DIR_PATH "/apps/aoview/log_dir"
-#define DEFAULT_LOG "AltOS"
-
-static char *aoview_log_dir;
-static FILE *aoview_log_file;
-static int aoview_log_serial;
-static int aoview_log_sequence;
-static GtkMessageDialog *log_fail_dialog;
-static int aoview_log_failed;
-
-static void
-aoview_log_save_conf(void)
-{
- GConfClient *gconf_client;
-
- gconf_client = gconf_client_get_default();
- if (gconf_client)
- {
- gconf_client_set_string(gconf_client,
- LOG_DIR_PATH,
- aoview_log_dir,
- NULL);
- g_object_unref(G_OBJECT(gconf_client));
- }
-}
-
-static void
-aoview_log_configure(GtkWidget *widget, gpointer data)
-{
- GtkFileChooser *chooser = data;
- aoview_log_dir = gtk_file_chooser_get_filename(chooser);
- aoview_log_save_conf();
- gtk_widget_hide(GTK_WIDGET(chooser));
-}
+static struct aoview_file *aoview_log;
void
aoview_log_new(void)
{
- if (aoview_log_file) {
- fclose(aoview_log_file);
- aoview_log_file = NULL;
- }
- aoview_log_failed = 0;
+ aoview_file_finish(aoview_log);
aoview_state_new();
}
-static void
-aoview_log_new_item(GtkWidget *widget, gpointer data)
-{
- aoview_log_new();
-}
-
void
aoview_log_set_serial(int serial)
{
- aoview_log_serial = serial;
+ aoview_file_set_serial(aoview_log, serial);
}
int
aoview_log_get_serial(void)
{
- return aoview_log_serial;
-}
-
-static void
-aoview_log_open_failed(char *name)
-{
- char *utf8_file;
- utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
- if (!utf8_file)
- utf8_file = name;
- gtk_message_dialog_format_secondary_text(log_fail_dialog,
- "\"%s\"", utf8_file);
- if (utf8_file != name)
- g_free(utf8_file);
- gtk_dialog_run(GTK_DIALOG(log_fail_dialog));
- gtk_widget_hide(GTK_WIDGET(log_fail_dialog));
- aoview_log_failed = 1;
-}
-
-static void
-aoview_log_start(void)
-{
- if (!aoview_log_file) {
- char base[50];
- struct tm tm;
- time_t now;
- char *full;
- int r;
-
- now = time(NULL);
- (void) localtime_r(&now, &tm);
- aoview_mkdir(aoview_log_dir);
- for (;;) {
- sprintf(base, "%04d-%02d-%02d-serial-%03d-flight-%03d.log",
- tm.tm_year + 1900,
- tm.tm_mon + 1,
- tm.tm_mday,
- aoview_log_serial,
- aoview_log_sequence);
- full = aoview_fullname(aoview_log_dir, base);
- r = access(full, F_OK);
- if (r < 0) {
- aoview_log_file = fopen(full, "w");
- if (!aoview_log_file)
- aoview_log_open_failed(full);
- else
- setlinebuf(aoview_log_file);
- free(full);
- break;
- }
- free (full);
- aoview_log_sequence++;
- }
- }
+ return aoview_file_get_serial(aoview_log);
}
void
@@ -139,56 +43,28 @@ aoview_log_printf(char *format, ...)
{
va_list ap;
- if (aoview_log_failed)
- return;
- aoview_log_start();
va_start(ap, format);
- vfprintf(aoview_log_file, format, ap);
+ aoview_file_vprintf(aoview_log, format, ap);
va_end(ap);
}
+static void
+aoview_log_new_item(GtkWidget *widget, gpointer data)
+{
+ aoview_file_finish(aoview_log);
+}
+
void
aoview_log_init(GladeXML *xml)
{
- GConfClient *gconf_client;
- char *log_dir = NULL;
- GtkFileChooser *log_chooser_dialog;
- GtkWidget *log_configure_ok;
GtkWidget *log_new;
- g_type_init();
- gconf_client = gconf_client_get_default();
- if (gconf_client)
- {
- log_dir = gconf_client_get_string(gconf_client,
- LOG_DIR_PATH,
- NULL);
- g_object_unref(G_OBJECT(gconf_client));
- }
- if (!log_dir) {
- aoview_log_dir = aoview_fullname(getenv("HOME"), DEFAULT_LOG);
- aoview_log_save_conf();
- } else {
- aoview_log_dir = strdup(log_dir);
- }
+ aoview_log = aoview_file_new("log");
+ assert(aoview_log);
- log_chooser_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "log_chooser_dialog"));
- assert(log_chooser_dialog);
- gtk_file_chooser_set_filename(log_chooser_dialog, aoview_log_dir);
-
- log_configure_ok = glade_xml_get_widget(xml, "log_configure_ok");
- assert(log_configure_ok);
-
- g_signal_connect(G_OBJECT(log_configure_ok), "clicked",
- G_CALLBACK(aoview_log_configure),
- log_chooser_dialog);
-
- log_new = glade_xml_get_widget(xml, "ao_log_new");
+ log_new = glade_xml_get_widget(xml, "log_new");
assert(log_new);
g_signal_connect(G_OBJECT(log_new), "activate",
G_CALLBACK(aoview_log_new_item),
NULL);
-
- log_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "log_fail_dialog"));
- assert(log_fail_dialog);
}
diff --git a/aoview/aoview_main.c b/aoview/aoview_main.c
index a3dc9544..8d000993 100644
--- a/aoview/aoview_main.c
+++ b/aoview/aoview_main.c
@@ -81,6 +81,8 @@ int main(int argc, char **argv)
aoview_state_init(xml);
+ aoview_file_init(xml);
+
aoview_log_init(xml);
aoview_table_init(xml);