From: Keith Packard Date: Wed, 20 May 2009 16:44:55 +0000 (-0700) Subject: Make file handling more general so it can be reused. X-Git-Tag: 0.5~70 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=aa6d87aeb616dd62f0debaded297232022b4f8bd 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 --- 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 @@ True - + _New log True True @@ -181,12 +181,12 @@ - + _Configure Log True True False - + True @@ -315,7 +315,7 @@ - + 5 Configure Log Directory dialog @@ -331,13 +331,13 @@ True end - + gtk-cancel True True True True - + False @@ -346,7 +346,7 @@ - + gtk-ok True True @@ -371,7 +371,7 @@ - + 5 Failed to create log normal 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 + * + * 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);