Index: navit/log.c
===================================================================
--- navit/log.c (revisão 5496)
+++ navit/log.c (cópia de trabalho)
@@ -36,6 +36,7 @@
#include "event.h"
#include "callback.h"
#include "debug.h"
+#include "util.h"
#include "log.h"
struct log_data {
@@ -71,10 +72,21 @@
{
time_t t;
struct tm *tm;
+ char *new_fmt_str;
t=time(NULL);
tm=localtime(&t);
- strftime(buffer, 4096, fmt, tm);
+ // Exchange all '%i' by '%%i' in the passed format string, if found.
+ new_fmt_str=g_strdup_replace_util(fmt, "%i", "%%i", -1);
+ // Since strftime does not define the '%i' format string option,
+ // and so could behave differently across c library implementation,
+ // it needs to be passed as '%%i' instead, because '%%' is defined,
+ // so strftime will format it back to '%i' again on the buffer.
+ strftime(buffer, 4096, new_fmt_str, tm);
+ // Free the memory space used by the modified format string.
+ dbg(0,"strftime_localtime: fmt=%s; new_fmt_str=%s; buffer=%s\n",
+ fmt, new_fmt_str, buffer);
+ g_free(new_fmt_str);
}
static void
@@ -86,18 +98,19 @@
strftime_localtime(buffer, 4096, this_->filename);
this_->filename_ex1=g_strdup(buffer);
if ((pos=strstr(this_->filename_ex1,"%i"))) {
-#ifdef HAVE_API_ANDROID
- pos[1]='d';
-#endif
i=0;
do {
g_free(this_->filename_ex2);
- this_->filename_ex2=g_strdup_printf(this_->filename_ex1,i++);
+ // Convert the sequential integer to string representation,
+ // reusing the local char buffer to store the result.
+ g_snprintf(buffer, 4096, "%d", i++);
+ // Replace all occurrences of '%i' formatting option in filename,
+ // each by the sequential integer in string representation stored in the buffer.
+ this_->filename_ex2=g_strdup_replace_util(this_->filename_ex1,"%i", buffer, -1);
+ dbg(0,"expand_filenames: filename_ex1=%s; filename_ex2=%s\n",
+ this_->filename_ex1, this_->filename_ex2);
} while (file_exists(this_->filename_ex2));
-#ifdef HAVE_API_ANDROID
- pos[1]='i';
-#endif
- } else
+ } else
this_->filename_ex2=g_strdup(this_->filename_ex1);
}
@@ -124,7 +137,7 @@
this_->f=fopen(this_->filename_ex2, "w");
if (! this_->f)
return;
- if (!this_->overwrite)
+ if (!this_->overwrite)
fseek(this_->f, 0, SEEK_END);
this_->empty = !ftell(this_->f);
log_set_last_flush(this_);
@@ -135,7 +148,7 @@
{
if (! this_->f)
return;
- if (this_->trailer.len)
+ if (this_->trailer.len)
fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f);
fflush(this_->f);
fclose(this_->f);
@@ -154,7 +167,7 @@
if (! this_->f)
return;
if (this_->empty) {
- if (this_->header.len)
+ if (this_->header.len)
fwrite(this_->header.data, 1, this_->header.len, this_->f);
if (this_->header.len || this_->data.len)
this_->empty=0;
@@ -170,7 +183,7 @@
pos=ftell(this_->f);
if (pos > 0) {
fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f);
- fseek(this_->f, pos, SEEK_SET);
+ fseek(this_->f, pos, SEEK_SET);
}
}
if (flags & log_flag_keep_pointer)
Index: navit/navit_shipped.xml
===================================================================
--- navit/navit_shipped.xml (revisão 5496)
+++ navit/navit_shipped.xml (cópia de trabalho)
@@ -170,7 +170,7 @@
source="serial:COM4 baud=4800 parity=N data=8 stop=1" > -->
-
+
Index: navit/util.c
===================================================================
--- navit/util.c (revisão 5496)
+++ navit/util.c (cópia de trabalho)
@@ -103,6 +103,96 @@
return ret;
}
+/**
+ * Implements a very basic utility function to replace a given substring match
+ * by another of arbitrary length on the input string.
+ *
+ * It's implemented in simple and straightforward way by allocating
+ * exact memory amount for the result just once, and aggregating the
+ * strings in it.
+ * Warning: This function accepts c-style, null terminated strings only.
+ * It relies mainly on strlen and strstr standard c library functions,
+ * it also uses glib string utility and memory management functions,
+ * so any limitation to those functions should apply.
+ * It also assumes that a char/gchar type will always be equals to a byte,
+ * and that arithmetic operation on pointers to char type will increment or
+ * decrement in byte sized quantities.
+ *
+ * @param in input_s input string.
+ * @param in search_s substring to match and to be replaced in the
+ * input string. If NULL, a copy of input string
+ * is returned. If it is empty and input string length is
+ * greater than zero, a copy of input string
+ * is returned.
+ * @param in replace_s replacement string. If NULL, a copy of input string
+ * is returned. If input and search strings are both empty,
+ * a copy of replace string is returned.
+ * @param in n_subst number up to substitutions to be made from the
+ * start of the input string, -1 to replace all. If 0, a copy
+ * of input string is returned.
+ * @return new string with replaced occurrences of search by replace
+ * string, use gfree() to free after use.
+ */
+gchar *
+g_strdup_replace_util(const gchar *input_s, const gchar *search_s,
+ const gchar *replace_s, gint n_subst) {
+ gchar *ret;
+ gint match_count = 0;
+ const gchar *scan_ptr = input_s, *match_ptr;
+ glong input_len, unchanged_len, match_len, replace_len, result_len = 0;
+ gsize alloc_size;
+ // Validate the inputs in order to prevent unexpected behaviour
+ if (!input_s || !search_s || !replace_s || !n_subst)
+ return g_strdup(input_s);
+ // Handle special cases first.
+ if ('\0' == *search_s) {
+ if ('\0' == *input_s)
+ return g_strdup(replace_s);
+ else
+ return g_strdup(input_s);
+ }
+ // Get the matching string pattern length.
+ match_len = strlen(search_s);
+ // Count the number of substitutions to be made on the input string.
+ while (((match_count < n_subst) || (-1 >= n_subst)) &&
+ (match_ptr = strstr(scan_ptr, search_s))) {
+ // Advance the string scanning pointer to the position
+ // just after the end of matched string segment.
+ scan_ptr = match_ptr + match_len;
+ // Count the number of matches done.
+ ++match_count;
+ }
+ // Get the input string length.
+ input_len = (gsize) (scan_ptr - input_s) + strlen(scan_ptr);
+ // Get the replacement string length.
+ replace_len = strlen(replace_s);
+ // Allocate memory space for result including the terminating null byte.
+ alloc_size = input_len - match_count * match_len + match_count * replace_len + 1;
+ //printf("mc=%d, ml=%ld, il=%ld, rl=%ld, alloc=%d, ", match_count, match_len, input_len, replace_len, alloc_size);
+ ret = g_new(gchar, alloc_size);
+ // Scan the input string again and compose the resulting string.
+ for (scan_ptr = input_s; match_count &&
+ (match_ptr = strstr(scan_ptr, search_s));
+ scan_ptr = match_ptr + match_len) {
+ // Get the length of partial string that is left unchanged.
+ unchanged_len = (gsize) (match_ptr - scan_ptr);
+ // Copy and append an unchanged string chunk.
+ g_memmove(ret + result_len, scan_ptr, unchanged_len);
+ // Update the resulting string length after appending the unchanged string segment.
+ result_len += unchanged_len;
+ // Copy and append a replacement instance.
+ g_memmove(ret + result_len, replace_s, replace_len);
+ // Update the resulting string length after appending the replacement string.
+ result_len += replace_len;
+ // Decrement to update the remaining replacement left.
+ --match_count;
+ }
+ // Copy the remaining chunk including the null byte to complete the resulting string.
+ g_memmove(ret + result_len, scan_ptr, input_len - (scan_ptr - input_s) + 1);
+ // Finally, return the resulting new string.
+ return ret;
+}
+
#ifndef HAVE_GLIB
int g_utf8_strlen_force_link(gchar *buffer, int max);
int
Index: navit/util.h
===================================================================
--- navit/util.h (revisão 5496)
+++ navit/util.h (cópia de trabalho)
@@ -28,6 +28,7 @@
GList * g_hash_to_list(GHashTable *h);
GList * g_hash_to_list_keys(GHashTable *h);
gchar * g_strconcat_printf(gchar *buffer, gchar *fmt, ...);
+gchar * g_strdup_replace_util(const gchar *input_s, const gchar *search_s, const gchar *replace_s, gint n_subst);
#if defined(_WIN32) || defined(__CEGCC__) || defined (__APPLE__) || defined(HAVE_API_ANDROID)
#if defined(_UNICODE)
wchar_t* newSysString(const char *toconvert);