X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fhomebank;a=blobdiff_plain;f=src%2Fhb-misc.c;h=ec904c9cd7572348e856660ecf2193efada9ad59;hp=b0e7600de8e263e92af55ac5ec31eba5d69a00fa;hb=5499ff44ef50b751b58f27fd13594f7dd4f959b7;hpb=996fa4ab9f6b836001f8ad0eecbfd3821687fea7 diff --git a/src/hb-misc.c b/src/hb-misc.c index b0e7600..ec904c9 100644 --- a/src/hb-misc.c +++ b/src/hb-misc.c @@ -1,5 +1,5 @@ /* HomeBank -- Free, easy, personal accounting for everyone. - * Copyright (C) 1995-2016 Maxime DOYEN + * Copyright (C) 1995-2019 Maxime DOYEN * * This file is part of HomeBank. * @@ -37,11 +37,11 @@ extern struct Preferences *PREFS; /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -static const double fac[7] = { 1, 10, 100, 1000, 10000, 100000, 1000000 }; +static const double fac[9] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; double hb_amount_round(const double x, unsigned int digits) { - digits = MAX(digits, 6); + digits = MAX(digits, 8); return floor((x * fac[digits]) + 0.5) / fac[digits]; } @@ -52,8 +52,7 @@ double hb_amount_round(const double x, unsigned int digits) gdouble hb_amount_to_euro(gdouble amount) { - return hb_amount_round((amount / PREFS->euro_value), 2); - //return hb_amount_round((amount * PREFS->euro_value), PREFS.minor_cur->frac_digits); + return hb_amount_round((amount * PREFS->euro_value), PREFS->minor_cur.frac_digits); } @@ -224,14 +223,16 @@ gdouble monval; } else { + monval = hb_amount_base(value, kcur); + monval = hb_amount_to_euro(monval); cur = &PREFS->minor_cur; - monval = hb_amount_to_euro(value); g_ascii_formatd(formatd_buf, outlen, cur->format, monval); hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE); } } + void hb_strfmon_int(gchar *outstr, gint outlen, gdouble value, guint32 kcur, gboolean minor) { gchar formatd_buf[outlen]; @@ -250,8 +251,9 @@ gdouble monval; } else { + monval = hb_amount_base(value, kcur); + monval = hb_amount_to_euro(monval); cur = &PREFS->minor_cur; - monval = hb_amount_to_euro(value); g_ascii_formatd(formatd_buf, outlen, cur->format, monval); hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE); } @@ -271,7 +273,7 @@ gdouble monval; if(cur != NULL) { monval = hb_amount_round(value, cur->frac_digits); - g_ascii_formatd(formatd_buf, outlen, "%0.f", monval); + g_ascii_formatd(formatd_buf, outlen, "%.2f", monval); hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE); } } @@ -279,7 +281,7 @@ gdouble monval; { cur = &PREFS->minor_cur; monval = hb_amount_to_euro(value); - g_ascii_formatd(formatd_buf, outlen, "%0.f", monval); + g_ascii_formatd(formatd_buf, outlen, "%.2f", monval); hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE); } @@ -287,7 +289,6 @@ gdouble monval; } - gchar *get_normal_color_amount(gdouble value) { gchar *color = NULL; @@ -385,6 +386,39 @@ end: } +gint hb_string_utf8_strstr(gchar *haystack, gchar *needle, gboolean exact) +{ +gint retval = FALSE; + + if( exact ) + { + if( g_strstr_len(haystack, -1, needle) != NULL ) + { + DB( g_print(" found case '%s'\n", needle) ); + retval = 1; + } + } + else + { + gchar *nchaystack = g_utf8_casefold(haystack, -1); + gchar *ncneedle = g_utf8_casefold(needle, -1); + + if( g_strrstr(nchaystack, ncneedle) != NULL ) + { + DB( g_print(" found nocase '%s'\n", ncneedle) ); + retval = 1; + } + + g_free(nchaystack); + g_free(ncneedle); + } + return retval; +} + + + + + /* * compare 2 utf8 string */ @@ -453,7 +487,52 @@ gchar *d = str; } -/*static void strip_extra_spaces(char* str) { +gchar *hb_string_copy_jsonpair(gchar *dst, gchar *str) +{ + + while( *str!='\0' ) + { + if( *str=='}' ) + break; + + if( *str==',' ) + { + *dst = '\0'; + return str + 1; + } + + if( *str!='{' && *str!='\"' ) + { + *dst++ = *str; + } + str++; + } + *dst = '\0'; + return NULL; +} + + +void hb_string_inline(gchar *str) +{ +gchar *s = str; +gchar *d = str; + + if(str) + { + while( *s ) + { + if( !(*s==' ' || *s=='\t' || *s=='\n' || *s=='\r') ) + { + *d++ = *s; + } + s++; + } + *d = 0; + } +} + + +/*void strip_extra_spaces(char* str) { int i,x; for(i=x=1; str[i]; ++i) if(!isspace(str[i]) || (i>0 && !isspace(str[i-1]))) @@ -491,6 +570,62 @@ hb_strdup_nobrackets (const gchar *str) } +/* if we found a . or , within last x digits it might be a dchar */ +static gchar hb_string_raw_amount_guess_dchar(const gchar *s, gint len, gshort digit) +{ +gint nbc, nbd, i; +gchar gdc='?'; + + DB( g_print(" digit=%d maxidx=%d\n", digit, len-digit-1) ); + + nbc = nbd = 0; + for(i=len-1;i>=0;i--) + { + DB( g_print(" [%2d] '%c' %d %d '%c'\n", i, s[i], nbc, nbd, gdc) ); + //store rightmost ,. within digit-1 + if( i>=(len-digit-1) ) + { + if(s[i]=='.' || s[i]==',') + gdc=s[i]; + } + if(s[i]=='.') nbd++; + else if(s[i]==',') nbc++; + } + if( gdc=='.' && nbd > 1) gdc='?'; + else if( gdc==',' && nbc > 1) gdc='?'; + + return gdc; +} + + +gchar *hb_string_dup_raw_amount_clean(const gchar *string, gint digits) +{ +gint l; +gchar *new_str, *d; +gchar gdc; +const gchar *p = string; + + l = strlen(string); + gdc = hb_string_raw_amount_guess_dchar(string, l, digits); + + new_str = d = g_malloc (l+1); + while(*p) + { + if(*p=='-' || g_ascii_isdigit(*p) ) + *d++ = *p; + else + if( *p==gdc ) + { + *d++ = '.'; + } + p++; + } + *d++ = '\0'; + + return new_str; +} + + static gboolean hb_date_parser_get_nums(gchar *string, gint *n1, gint *n2, gint *n3) { @@ -500,30 +635,32 @@ gchar **str_array; //DB( g_print("(qif) hb_qif_parser_get_dmy for '%s'\n", string) ); retval = FALSE; - str_array = g_strsplit (string, "/", 3); - if( g_strv_length( str_array ) != 3 ) + if( string ) { - g_strfreev (str_array); - str_array = g_strsplit (string, ".", 3); - // fix 371381 - //todo test + str_array = g_strsplit (string, "/", 3); if( g_strv_length( str_array ) != 3 ) { g_strfreev (str_array); - str_array = g_strsplit (string, "-", 3); + str_array = g_strsplit (string, ".", 3); + // fix 371381 + //todo test + if( g_strv_length( str_array ) != 3 ) + { + g_strfreev (str_array); + str_array = g_strsplit (string, "-", 3); + } } - } - if( g_strv_length( str_array ) == 3 ) - { - *n1 = atoi(str_array[0]); - *n2 = atoi(str_array[1]); - *n3 = atoi(str_array[2]); - retval = TRUE; - } - - g_strfreev (str_array); + if( g_strv_length( str_array ) == 3 ) + { + *n1 = atoi(str_array[0]); + *n2 = atoi(str_array[1]); + *n3 = atoi(str_array[2]); + retval = TRUE; + } + g_strfreev (str_array); + } return retval; } @@ -591,31 +728,174 @@ guint32 julian = 0; /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ - -gchar *hb_util_filename_new_with_extension(gchar *filename, const gchar *extension) +gint hb_filename_type_get_by_extension(gchar *filepath) { -gchar *lastdot, *fwe; -gchar *newfilename; +gint retval = FILETYPE_UNKNOWN; +gint str_len; - DB( g_print("\n[util] filename with extension\n") ); + g_return_val_if_fail(filepath != NULL, FILETYPE_UNKNOWN); + + str_len = strlen(filepath); + if( str_len >= 4 ) + { + if( strcasecmp(filepath + str_len - 4, ".ofx") == 0) + retval = FILETYPE_OFX; + else + if( strcasecmp(filepath + str_len - 4, ".qif") == 0) + retval = FILETYPE_QIF; + else + if( strcasecmp(filepath + str_len - 4, ".qfx") == 0) + retval = FILETYPE_OFX; + else + if( strcasecmp(filepath + str_len - 4, ".csv") == 0) + retval = FILETYPE_CSV_HB; + else + if( strcasecmp(filepath + str_len - 4, ".xhb") == 0) + retval = FILETYPE_HOMEBANK; + } + return retval; +} - DB( g_print(" - orig: '%s' => '%s'\n", filename, extension) ); - //duplicate without extensions - lastdot = g_strrstr(filename, "."); +static gchar *hb_filename_new_without_extension(gchar *filename) +{ +gchar *lastdot; + + lastdot = g_strrstr (filename, "."); if(lastdot != NULL) { - fwe = g_strndup(filename, strlen(filename) - strlen(lastdot)); - DB( g_print(" - fwe: '%s'\n", fwe) ); - newfilename = g_strdup_printf("%s.%s", fwe, extension); - g_free(fwe); + return g_strndup(filename, strlen(filename) - strlen(lastdot)); } - else + return g_strdup(filename); +} + + +static gint hb_filename_backup_list_sort_func(gchar **a, gchar **b) +{ +gint da = atoi( *a + strlen(*a) - 12); +gint db = atoi( *b + strlen(*b) - 12); + + return db - da; +} + + +GPtrArray *hb_filename_backup_list(gchar *filename) +{ +gchar *dirname, *basename; +gchar *rawfilename, *pattern; +GDir *dir; +const gchar *tmpname; +GPatternSpec *pspec; +GPtrArray *array; + + DB( g_print("\n[util] filename backup list\n") ); + + dirname = g_path_get_dirname(filename); + basename = g_path_get_basename(filename); + + DB( g_print(" dir='%s' base='%s'\n", dirname, basename) ); + + rawfilename = hb_filename_new_without_extension(basename); + pattern = g_strdup_printf("%s-????????.bak", rawfilename); + + pspec = g_pattern_spec_new(pattern); + + + DB( g_print(" pattern='%s'\n", pattern) ); + + array = g_ptr_array_new_with_free_func(g_free); + + dir = g_dir_open (PREFS->path_hbfile, 0, NULL); + if (dir) { - newfilename = g_strdup_printf("%s.%s", filename, extension); + while ((tmpname = g_dir_read_name (dir)) != NULL) + { + gboolean match; + + match = g_pattern_match_string(pspec, tmpname); + if( match ) + { + DB( g_print(" %d => '%s'\n", match, tmpname) ); + g_ptr_array_add(array, g_strdup(tmpname)); + } + } } + g_free(pattern); + g_dir_close (dir); + g_pattern_spec_free(pspec); + g_free(rawfilename); + + g_free(basename); + g_free(dirname); + + g_ptr_array_sort(array, (GCompareFunc)hb_filename_backup_list_sort_func); + + return array; +} + + +gchar *hb_filename_backup_get_filtername(gchar *filename) +{ +gchar *dirname, *basename; +gchar *rawfilename, *pattern; + + DB( g_print("\n[util] filename backup get filtername\n") ); + + dirname = g_path_get_dirname(filename); + basename = g_path_get_basename(filename); + + DB( g_print(" dir='%s' base='%s'\n", dirname, basename) ); + + rawfilename = hb_filename_new_without_extension(basename); + + pattern = g_strdup_printf("%s*.[Bb][Aa][Kk]", rawfilename); + + g_free(rawfilename); + g_free(basename); + g_free(dirname); + + return pattern; +} + + +gchar *hb_filename_new_for_backup(gchar *filename) +{ +gchar *rawfilename, *newfilename; +GDate date; - DB( g_print(" - new: '%s'\n", newfilename) ); + DB( g_print("\n[util] filename new for backup\n") ); + + rawfilename = hb_filename_new_without_extension(filename); + + g_date_clear(&date, 1); + g_date_set_julian (&date, GLOBALS->today); + + newfilename = g_strdup_printf("%s-%04d%02d%02d.bak", + rawfilename, + g_date_get_year(&date), + g_date_get_month(&date), + g_date_get_day(&date) + ); + + g_free(rawfilename); + + DB( g_print(" - '%s' => '%s'\n", filename, newfilename) ); + + return newfilename; +} + + +gchar *hb_filename_new_with_extension(gchar *filename, const gchar *extension) +{ +gchar *rawfilename, *newfilename; + + DB( g_print("\n[util] filename new with extension\n") ); + + rawfilename = hb_filename_new_without_extension(filename); + newfilename = g_strdup_printf("%s.%s", rawfilename, extension); + g_free(rawfilename); + + DB( g_print(" - '%s' => '%s'\n", filename, newfilename) ); return newfilename; } @@ -696,7 +976,8 @@ GDate date; g_date_get_month(&date), g_date_get_year(&date) ); - } + } + break; default: g_sprintf(outstr, "%04d/%02d/%02d", g_date_get_year(&date),