g_hash_table_foreach(table, hash_free_strings_func, NULL);
}
+static void hash_free_value_mem_func(gpointer key, gpointer value,
+ gpointer data)
+{
+ g_free(value);
+}
+
+void hash_free_value_mem(GHashTable *table)
+{
+ g_hash_table_foreach(table, hash_free_value_mem_func, NULL);
+}
+
void ptr_array_free_strings(GPtrArray *array)
{
gint i;
return str;
}
+/* remove trailing character */
+gchar *strtailchomp(gchar *str, gchar tail_char)
+{
+ register gchar *s;
+
+ if (!*str) return str;
+ if (tail_char == '\0') return str;
+
+ for (s = str + strlen(str) - 1; s >= str && *s == tail_char; s--)
+ *s = '\0';
+
+ return str;
+}
+
+
/* Similar to `strstr' but this function ignores the case of both strings. */
gchar *strcasestr(const gchar *haystack, const gchar *needle)
{
if (!*str1 || !*str2) return -1;
retval = strcmp(str1, str2);
- //if (retval == 0)
- // g_print("\ns1 = %s\ns2 = %s\n"
- // "str1 = %s\nstr2 = %s\nmatched.\n",
- // s1, s2, str1, str2);
-
+ /*
+ if (retval == 0)
+ g_print("\ns1 = %s\ns2 = %s\n"
+ "str1 = %s\nstr2 = %s\nmatched.\n",
+ s1, s2, str1, str2);
+ */
return retval;
}
return 0;
}
-gint remove_all_numbered_files(const gchar *dir)
+gint remove_numbered_files(const gchar *dir, guint first, guint last)
{
DIR *dp;
struct dirent *d;
gchar *prev_dir;
+ gint fileno;
prev_dir = g_get_current_dir();
}
while ((d = readdir(dp)) != NULL) {
- if (to_number(d->d_name) < 0) continue;
-
- if (unlink(d->d_name) < 0)
- FILE_OP_ERROR(d->d_name, "unlink");
+ fileno = to_number(d->d_name);
+ if (fileno >= 0 && first <= fileno && fileno <= last) {
+ if (unlink(d->d_name) < 0)
+ FILE_OP_ERROR(d->d_name, "unlink");
+ }
}
closedir(dp);
return 0;
}
+gint remove_all_numbered_files(const gchar *dir)
+{
+ return remove_numbered_files(dir, 0, UINT_MAX);
+}
+
gint remove_dir_recursive(const gchar *dir)
{
struct stat s;
struct dirent *d;
gchar *prev_dir;
- //g_print("dir = %s\n", dir);
+ /*g_print("dir = %s\n", dir);*/
if (stat(dir, &s) < 0) {
FILE_OP_ERROR(dir, "stat");
}
prev_dir = g_get_current_dir();
- //g_print("prev_dir = %s\n", prev_dir);
+ /*g_print("prev_dir = %s\n", prev_dir);*/
if (!path_cmp(prev_dir, dir)) {
g_free(prev_dir);
continue;
}
- //g_print("removing %s\n", d->d_name);
+ /*g_print("removing %s\n", d->d_name);*/
if (S_ISDIR(s.st_mode)) {
if (remove_dir_recursive(d->d_name) < 0) {
day, dd, mon, yyyy, hh, mm, ss, tzoffset(&t));
}
+static FILE *log_fp = NULL;
+
+void set_log_file(const gchar *filename)
+{
+ if (log_fp) return;
+ log_fp = fopen(filename, "w");
+ if (!log_fp)
+ FILE_OP_ERROR(filename, "fopen");
+}
+
+void close_log_file(void)
+{
+ if (log_fp) {
+ fclose(log_fp);
+ log_fp = NULL;
+ }
+}
+
void debug_print(const gchar *format, ...)
{
va_list args;
{
va_list args;
gchar buf[BUFFSIZE];
+ gchar *logbuf;
+ gchar timestr[6];
+ time_t t;
va_start(args, format);
g_vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
+
+ time(&t);
+ strftime(timestr, 6, "%H:%M", localtime(&t));
+ logbuf = g_strdup_printf("[%s] %s", timestr, buf);
- if (debug_mode) fputs(buf, stdout);
- log_window_append(buf, LOG_NORMAL);
+ if (debug_mode) fputs(logbuf, stdout);
+ log_window_append(logbuf, LOG_NORMAL);
+ if (log_fp) {
+ fputs(logbuf, log_fp);
+ fflush(log_fp);
+ }
statusbar_puts_all(buf);
+
+ g_free(logbuf);
}
void log_message(const gchar *format, ...)
if (debug_mode) g_message("%s", buf);
log_window_append(buf, LOG_MSG);
+ if (log_fp) {
+ fputs("message: ", log_fp);
+ fputs(buf, log_fp);
+ fflush(log_fp);
+ }
}
void log_warning(const gchar *format, ...)
g_warning("%s", buf);
log_window_append(buf, LOG_WARN);
+ if (log_fp) {
+ fputs("*** warning: ", log_fp);
+ fputs(buf, log_fp);
+ fflush(log_fp);
+ }
}
void log_error(const gchar *format, ...)
g_warning("%s", buf);
log_window_append(buf, LOG_ERROR);
+ if (log_fp) {
+ fputs("*** error: ", log_fp);
+ fputs(buf, log_fp);
+ fflush(log_fp);
+ }
}