Ticket #1112: navit_new_search_replace_function_and_sequential_log_number_fix.patch

File navit_new_search_replace_function_and_sequential_log_number_fix.patch, 8.8 KB (added by leonardohamada, 7 years ago)

Updated patch

  • navit/log.c

     
    3636#include "event.h"
    3737#include "callback.h"
    3838#include "debug.h"
     39#include "util.h"
    3940#include "log.h"
    4041
    4142struct log_data {
     
    7172{
    7273        time_t t;
    7374        struct tm *tm;
     75        char *new_fmt_str;
    7476
    7577        t=time(NULL);
    7678        tm=localtime(&t);
    77         strftime(buffer, 4096, fmt, tm);
     79        // Exchange all '%i' by '%%i' in the passed format string, if found.
     80        new_fmt_str=g_strdup_replace_util(fmt, "%i", "%%i", -1);
     81        // Since strftime does not define the '%i' format string option,
     82        // and so could behave differently across c library implementation,
     83        // it needs to be passed as '%%i' instead, because '%%' is defined,
     84        // so strftime will format it back to '%i' again on the buffer.
     85        strftime(buffer, 4096, new_fmt_str, tm);
     86        // Free the memory space used by the modified format string.
     87        dbg(0,"strftime_localtime: fmt=%s; new_fmt_str=%s; buffer=%s\n",
     88                fmt, new_fmt_str, buffer);
     89        g_free(new_fmt_str);
    7890}
    7991
    8092static void
     
    8698        strftime_localtime(buffer, 4096, this_->filename);
    8799        this_->filename_ex1=g_strdup(buffer);
    88100        if ((pos=strstr(this_->filename_ex1,"%i"))) {
    89 #ifdef HAVE_API_ANDROID
    90                 pos[1]='d';
    91 #endif
    92101                i=0;
    93102                do {
    94103                        g_free(this_->filename_ex2);
    95                         this_->filename_ex2=g_strdup_printf(this_->filename_ex1,i++);
     104                        // Convert the sequential integer to string representation,
     105                        // reusing the local char buffer to store the result.
     106                        g_snprintf(buffer, 4096, "%d", i++);
     107                        // Replace all occurrences of '%i' formatting option in filename,
     108                        // each by the sequential integer in string representation stored in the buffer.
     109                        this_->filename_ex2=g_strdup_replace_util(this_->filename_ex1,"%i", buffer, -1);
     110                        dbg(0,"expand_filenames: filename_ex1=%s; filename_ex2=%s\n",
     111                                this_->filename_ex1, this_->filename_ex2);
    96112                } while (file_exists(this_->filename_ex2));
    97 #ifdef HAVE_API_ANDROID
    98                 pos[1]='i';
    99 #endif
    100         } else
     113        } else
    101114                this_->filename_ex2=g_strdup(this_->filename_ex1);
    102115}
    103116
     
    124137                this_->f=fopen(this_->filename_ex2, "w");
    125138        if (! this_->f)
    126139                return;
    127         if (!this_->overwrite) 
     140        if (!this_->overwrite)
    128141                fseek(this_->f, 0, SEEK_END);
    129142        this_->empty = !ftell(this_->f);
    130143        log_set_last_flush(this_);
     
    135148{
    136149        if (! this_->f)
    137150                return;
    138         if (this_->trailer.len) 
     151        if (this_->trailer.len)
    139152                fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f);
    140153        fflush(this_->f);
    141154        fclose(this_->f);
     
    154167        if (! this_->f)
    155168                return;
    156169        if (this_->empty) {
    157                 if (this_->header.len) 
     170                if (this_->header.len)
    158171                        fwrite(this_->header.data, 1, this_->header.len, this_->f);
    159172                if (this_->header.len || this_->data.len)
    160173                        this_->empty=0;
     
    170183                pos=ftell(this_->f);
    171184                if (pos > 0) {
    172185                        fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f);
    173                         fseek(this_->f, pos, SEEK_SET); 
     186                        fseek(this_->f, pos, SEEK_SET);
    174187                }
    175188        }
    176189        if (flags & log_flag_keep_pointer)
  • navit/navit_shipped.xml

     
    170170                                source="serial:COM4 baud=4800 parity=N data=8 stop=1" > -->
    171171
    172172                        <!-- Navit can write a tracklog in several formats (gpx, nmea or textfile): -->
    173                         <log enabled="no" type="gpx" attr_types="position_time_iso8601,position_direction,position_speed,profilename,position_radius" data="track_%Y%m%d-%%i.gpx" flush_size="1000" flush_time="30"/>
     173                        <log enabled="no" type="gpx" attr_types="position_time_iso8601,position_direction,position_speed,profilename,position_radius" data="track_%Y%m%d-%i.gpx" flush_size="1000" flush_time="30"/>
    174174                </vehicle>
    175175
    176176                <!-- For SDL, you should add follow="1" to have the view centered on your position -->
  • navit/util.c

     
    103103        return ret;
    104104}
    105105
     106/**
     107 *  Implements a very basic utility function to replace a given substring match
     108 *          by another of arbitrary length on the input string.
     109 *
     110 *      It's implemented in simple and straightforward way by allocating
     111 *  exact memory amount for the result just once, and aggregating the
     112 *  strings in it.
     113 *  Warning: This function accepts c-style, null terminated strings only.
     114 *  It relies mainly on strlen and strstr standard c library functions,
     115 *  it also uses glib string utility and memory management functions,
     116 *  so any limitation to those functions should apply.
     117 *  It also assumes that a char/gchar type will always be equals to a byte,
     118 *  and that arithmetic operation on pointers to char type will increment or
     119 *  decrement in byte sized quantities.
     120 *
     121 *  @param in input_s input string.
     122 *  @param in search_s substring to match and to be replaced in the
     123 *         input string. If NULL, a copy of input string
     124 *         is returned. If it is empty and input string length is
     125 *         greater than zero, a copy of input string
     126 *         is returned.
     127 *  @param in replace_s replacement string. If NULL, a copy of input string
     128 *         is returned. If input and search strings are both empty,
     129 *         a copy of replace string is returned.
     130 *  @param in n_subst number up to substitutions to be made from the
     131 *         start of the input string, -1 to replace all. If 0, a copy
     132 *         of input string is returned.
     133 *  @return new string with replaced occurrences of search by replace
     134 *         string, use gfree() to free after use.
     135 */
     136gchar *
     137g_strdup_replace_util(const gchar *input_s, const gchar *search_s,
     138                                const gchar *replace_s, gint n_subst) {
     139        gchar *ret;
     140        gint match_count = 0;
     141        const gchar *scan_ptr = input_s, *match_ptr;
     142        glong input_len, unchanged_len, match_len, replace_len, result_len = 0;
     143        gsize alloc_size;
     144        // Validate the inputs in order to prevent unexpected behaviour
     145        if (!input_s || !search_s || !replace_s || !n_subst)
     146                return g_strdup(input_s);
     147        // Handle special cases first.
     148        if ('\0' == *search_s) {
     149                if ('\0' == *input_s)
     150                        return g_strdup(replace_s);
     151                else
     152                        return g_strdup(input_s);
     153        }
     154        // Get the matching string pattern length.
     155        match_len = strlen(search_s);
     156        // Count the number of substitutions to be made on the input string.
     157        while (((match_count < n_subst) || (-1 >= n_subst)) &&
     158                        (match_ptr = strstr(scan_ptr, search_s))) {
     159                // Advance the string scanning pointer to the position
     160                // just after the end of matched string segment.
     161                scan_ptr = match_ptr + match_len;
     162                // Count the number of matches done.
     163                ++match_count;
     164        }
     165        // Get the input string length.
     166        input_len = (gsize) (scan_ptr - input_s) + strlen(scan_ptr);
     167        // Get the replacement string length.
     168        replace_len = strlen(replace_s);
     169        // Allocate memory space for result including the terminating null byte.
     170        alloc_size = input_len - match_count * match_len + match_count * replace_len + 1;
     171        //printf("mc=%d, ml=%ld, il=%ld, rl=%ld, alloc=%d, ", match_count, match_len, input_len, replace_len, alloc_size);
     172        ret = g_new(gchar, alloc_size);
     173        // Scan the input string again and compose the resulting string.
     174        for (scan_ptr = input_s; match_count &&
     175                        (match_ptr = strstr(scan_ptr, search_s));
     176                                        scan_ptr = match_ptr + match_len) {
     177                // Get the length of partial string that is left unchanged.
     178                unchanged_len = (gsize) (match_ptr - scan_ptr);
     179                // Copy and append an unchanged string chunk.
     180                g_memmove(ret + result_len, scan_ptr, unchanged_len);
     181                // Update the resulting string length after appending the unchanged string segment.
     182                result_len += unchanged_len;
     183                // Copy and append a replacement instance.
     184                g_memmove(ret + result_len, replace_s, replace_len);
     185                // Update the resulting string length after appending the replacement string.
     186                result_len += replace_len;
     187                // Decrement to update the remaining replacement left.
     188                --match_count;
     189        }
     190        // Copy the remaining chunk including the null byte to complete the resulting string.
     191        g_memmove(ret + result_len, scan_ptr, input_len - (scan_ptr - input_s) + 1);
     192        // Finally, return the resulting new string.
     193        return ret;
     194}
     195
    106196#ifndef HAVE_GLIB
    107197int g_utf8_strlen_force_link(gchar *buffer, int max);
    108198int
  • navit/util.h

     
    2828GList * g_hash_to_list(GHashTable *h);
    2929GList * g_hash_to_list_keys(GHashTable *h);
    3030gchar * g_strconcat_printf(gchar *buffer, gchar *fmt, ...);
     31gchar * g_strdup_replace_util(const gchar *input_s, const gchar *search_s, const gchar *replace_s, gint n_subst);
    3132#if defined(_WIN32) || defined(__CEGCC__) || defined (__APPLE__) || defined(HAVE_API_ANDROID)
    3233#if defined(_UNICODE)
    3334wchar_t* newSysString(const char *toconvert);