]> Dogcows Code - chaz/homebank/blob - src/hb-misc.c
import homebank-5.2.6
[chaz/homebank] / src / hb-misc.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 //nota: this file should be renamed hb-utils
22
23 #include "homebank.h"
24 #include "hb-misc.h"
25
26 #define MYDEBUG 0
27
28 #if MYDEBUG
29 #define DB(x) (x);
30 #else
31 #define DB(x);
32 #endif
33
34 /* our global datas */
35 extern struct HomeBank *GLOBALS;
36 extern struct Preferences *PREFS;
37
38 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
39
40 static const double fac[9] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
41
42 double hb_amount_round(const double x, unsigned int digits)
43 {
44 digits = MAX(digits, 8);
45 return floor((x * fac[digits]) + 0.5) / fac[digits];
46 }
47
48
49 // used to convert from national to euro currency
50 // used in hb_account.c :: only when convert account to euro
51 // round option is to 0.5 case so 1.32 is 1.3, but 1.35 is 1.4
52
53 gdouble hb_amount_to_euro(gdouble amount)
54 {
55 return hb_amount_round((amount * PREFS->euro_value), PREFS->minor_cur.frac_digits);
56 }
57
58
59 /* new >5.1 currency fct
60 *
61 * convert an amount in base currency
62 *
63 */
64 gdouble hb_amount_base(gdouble value, guint32 kcur)
65 {
66 gdouble newvalue;
67 Currency *cur;
68
69 if(kcur == GLOBALS->kcur)
70 return value;
71
72 cur = da_cur_get(kcur);
73 if(cur == NULL || cur->rate == 0.0)
74 return 0;
75
76 newvalue = value / cur->rate;
77 return hb_amount_round(newvalue, cur->frac_digits);
78 }
79
80
81 static Currency *hb_strfmon_check(gchar *outstr, guint32 kcur)
82 {
83 Currency *cur = da_cur_get(kcur);
84
85 if(cur == NULL)
86 g_stpcpy(outstr, "nan");
87 return cur;
88 }
89
90
91 gchar *hb_str_rate(gchar *outstr, gint outlen, gdouble rate)
92 {
93 gint count, i;
94 gchar *p;
95
96 count = g_snprintf(outstr, outlen, "%.6f", rate);
97 //remove trailing 0 and decimal point
98 p = &outstr[count-1];
99 for(i=count;i>0;i--)
100 {
101 if(*p == '0')
102 *p = '\0';
103 else
104 break;
105 p--;
106 }
107 if(*p == '.' || *p == ',')
108 *p = '\0';
109
110 return outstr;
111 }
112
113 /* this function copy a number 99999.99 at s into d and count
114 * number of digits for integer part and decimal part
115 */
116 static gchar * _strfnumcopycount(gchar *s, gchar *d, gchar *decchar, gint *plen, gint *pnbint, gint *pnbdec)
117 {
118 gint len=0, nbint=0, nbdec=0;
119
120 // sign part
121 if(*s == '-') {
122 *d++ = *s++;
123 len++;
124 }
125 // integer part
126 while(*s != 0 && *s != '.') {
127 *d++ = *s++;
128 nbint++;
129 len++;
130 }
131 // decimal separator
132 if(*s == '.') {
133 d = g_stpcpy(d, decchar);
134 len++;
135 s++;
136 }
137 // decimal part
138 while(*s != 0) {
139 *d++ = *s++;
140 nbdec++;
141 len++;
142 }
143 // end string | fill external count
144 *d = 0;
145 *plen = len;
146 *pnbint = nbint;
147 *pnbdec = nbdec;
148
149 return d;
150 }
151
152 //todo: used only in ui_prefs.c
153 gchar *hb_str_formatd(gchar *outstr, gint outlen, gchar *buf1, Currency *cur, gboolean showsymbol)
154 {
155 gint len, nbd, nbi;
156 gchar *s, *d, *tmp;
157
158 d = tmp = outstr;
159 if(showsymbol && cur->sym_prefix)
160 {
161 d = g_stpcpy (d, cur->symbol);
162 *d++ = ' ';
163 tmp = d;
164 }
165
166 d = _strfnumcopycount(buf1, d, cur->decimal_char, &len, &nbi, &nbd);
167
168 if( cur->grouping_char != NULL && strlen(cur->grouping_char) > 0 )
169 {
170 gint i, grpcnt;
171
172 s = buf1;
173 d = tmp;
174 if(*s == '-')
175 *d++ = *s++;
176
177 grpcnt = 4 - nbi;
178 for(i=0;i<nbi;i++)
179 {
180 *d++ = *s++;
181 if( !(grpcnt % 3) && i<(nbi-1))
182 {
183 d = g_stpcpy(d, cur->grouping_char);
184 }
185 grpcnt++;
186 }
187
188 if(nbd > 0)
189 {
190 d = g_stpcpy(d, cur->decimal_char);
191 d = g_stpcpy(d, s+1);
192 }
193 *d = 0;
194 }
195
196 if(showsymbol && !cur->sym_prefix)
197 {
198 *d++ = ' ';
199 d = g_stpcpy (d, cur->symbol);
200 }
201
202 *d = 0;
203
204 return d;
205 }
206
207
208 void hb_strfmon(gchar *outstr, gint outlen, gdouble value, guint32 kcur, gboolean minor)
209 {
210 gchar formatd_buf[outlen];
211 Currency *cur;
212 gdouble monval;
213
214 if(minor == FALSE)
215 {
216 cur = hb_strfmon_check(outstr, kcur);
217 if(cur != NULL)
218 {
219 monval = hb_amount_round(value, cur->frac_digits);
220 g_ascii_formatd(formatd_buf, outlen, cur->format, monval);
221 hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE);
222 }
223 }
224 else
225 {
226 monval = hb_amount_base(value, kcur);
227 monval = hb_amount_to_euro(monval);
228 cur = &PREFS->minor_cur;
229 g_ascii_formatd(formatd_buf, outlen, cur->format, monval);
230 hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE);
231 }
232
233 }
234
235
236 void hb_strfmon_int(gchar *outstr, gint outlen, gdouble value, guint32 kcur, gboolean minor)
237 {
238 gchar formatd_buf[outlen];
239 Currency *cur;
240 gdouble monval;
241
242 if(minor == FALSE)
243 {
244 cur = hb_strfmon_check(outstr, kcur);
245 if(cur != NULL)
246 {
247 monval = hb_amount_round(value, cur->frac_digits);
248 g_ascii_formatd(formatd_buf, outlen, "%0.f", monval);
249 hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE);
250 }
251 }
252 else
253 {
254 monval = hb_amount_base(value, kcur);
255 monval = hb_amount_to_euro(monval);
256 cur = &PREFS->minor_cur;
257 g_ascii_formatd(formatd_buf, outlen, cur->format, monval);
258 hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE);
259 }
260
261 }
262
263
264 void hb_strfnum(gchar *outstr, gint outlen, gdouble value, guint32 kcur, gboolean minor)
265 {
266 gchar formatd_buf[outlen];
267 Currency *cur;
268 gdouble monval;
269
270 if(minor == FALSE)
271 {
272 cur = hb_strfmon_check(outstr, kcur);
273 if(cur != NULL)
274 {
275 monval = hb_amount_round(value, cur->frac_digits);
276 g_ascii_formatd(formatd_buf, outlen, "%.2f", monval);
277 hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE);
278 }
279 }
280 else
281 {
282 cur = &PREFS->minor_cur;
283 monval = hb_amount_to_euro(value);
284 g_ascii_formatd(formatd_buf, outlen, "%.2f", monval);
285 hb_str_formatd(outstr, outlen, formatd_buf, cur, TRUE);
286 }
287
288
289 }
290
291
292 gchar *get_normal_color_amount(gdouble value)
293 {
294 gchar *color = NULL;
295
296 //fix: 400483
297 value = hb_amount_round(value, 2);
298
299 if(value != 0.0 && PREFS->custom_colors == TRUE)
300 {
301 color = (value > 0.0) ? PREFS->color_inc : PREFS->color_exp;
302 }
303 return color;
304 }
305
306
307 gchar *get_minimum_color_amount(gdouble value, gdouble minvalue)
308 {
309 gchar *color = NULL;
310
311 //fix: 400483
312 value = hb_amount_round(value, 2);
313 if(value != 0.0 && PREFS->custom_colors == TRUE)
314 {
315 color = (value > 0.0) ? PREFS->color_inc : PREFS->color_exp;
316 if( value < minvalue)
317 color = PREFS->color_warn;
318 }
319 return color;
320 }
321
322 void hb_label_set_amount(GtkLabel *label, gdouble value, guint32 kcur, gboolean minor)
323 {
324 gchar strbuffer[G_ASCII_DTOSTR_BUF_SIZE];
325
326 hb_strfmon(strbuffer, G_ASCII_DTOSTR_BUF_SIZE-1, value, kcur, minor);
327 gtk_label_set_text(GTK_LABEL(label), strbuffer);
328
329 }
330
331
332 /*
333 ** format/color and set a label text with a amount value
334 */
335 void hb_label_set_colvalue(GtkLabel *label, gdouble value, guint32 kcur, gboolean minor)
336 {
337 gchar strbuffer[G_ASCII_DTOSTR_BUF_SIZE];
338 gchar *markuptxt;
339 gchar *color = NULL;
340
341 hb_strfmon(strbuffer, G_ASCII_DTOSTR_BUF_SIZE-1, value, kcur, minor);
342
343 if(value != 0.0 && PREFS->custom_colors == TRUE)
344 {
345 color = get_normal_color_amount(value);
346
347 //g_print("color: %s\n", color);
348
349 if(color)
350 {
351 markuptxt = g_strdup_printf("<span color='%s'>%s</span>", color, strbuffer);
352 gtk_label_set_markup(GTK_LABEL(label), markuptxt);
353 g_free(markuptxt);
354 return;
355 }
356 }
357
358 gtk_label_set_text(GTK_LABEL(label), strbuffer);
359
360 }
361
362
363
364
365 /*
366 ** String utility
367 */
368
369 gint hb_string_compare(gchar *s1, gchar *s2)
370 {
371 gint retval = 0;
372
373 if (s1 == NULL || s2 == NULL)
374 {
375 if (s1 == NULL && s2 == NULL)
376 goto end;
377
378 retval = (s1 == NULL) ? -1 : 1;
379 }
380 else
381 {
382 retval = strcasecmp(s1, s2);
383 }
384 end:
385 return retval;
386 }
387
388
389 gint hb_string_utf8_strstr(gchar *haystack, gchar *needle, gboolean exact)
390 {
391 gint retval = FALSE;
392
393 if( exact )
394 {
395 if( g_strstr_len(haystack, -1, needle) != NULL )
396 {
397 DB( g_print(" found case '%s'\n", needle) );
398 retval = 1;
399 }
400 }
401 else
402 {
403 gchar *nchaystack = g_utf8_casefold(haystack, -1);
404 gchar *ncneedle = g_utf8_casefold(needle, -1);
405
406 if( g_strrstr(nchaystack, ncneedle) != NULL )
407 {
408 DB( g_print(" found nocase '%s'\n", ncneedle) );
409 retval = 1;
410 }
411
412 g_free(nchaystack);
413 g_free(ncneedle);
414 }
415 return retval;
416 }
417
418
419
420
421
422 /*
423 * compare 2 utf8 string
424 */
425 gint hb_string_utf8_compare(gchar *s1, gchar *s2)
426 {
427 gint retval = 0;
428 gchar *ns1, *ns2;
429
430 if (s1 == NULL || s2 == NULL)
431 {
432 if (s1 == NULL && s2 == NULL)
433 goto end;
434
435 retval = (s1 == NULL) ? -1 : 1;
436 }
437 else
438 {
439 //#1325969
440 //retval = g_utf8_collate(s1 != NULL ? s1 : "", s2 != NULL ? s2 : "");
441 ns1 = g_utf8_normalize(s1, -1, G_NORMALIZE_DEFAULT);
442 ns2 = g_utf8_normalize(s2, -1, G_NORMALIZE_DEFAULT);
443 retval = strcasecmp(ns1, ns2);
444 g_free(ns2);
445 g_free(ns1);
446 }
447 end:
448 return retval;
449 }
450
451
452 void hb_string_strip_crlf(gchar *str)
453 {
454 gchar *p = str;
455
456 if(str)
457 {
458 while( *p )
459 {
460 if( *p == '\n' || *p == '\r')
461 {
462 *p = '\0';
463 }
464 p++;
465 }
466 }
467 }
468
469
470 void hb_string_replace_char(gchar c, gchar *str)
471 {
472 gchar *s = str;
473 gchar *d = str;
474
475 if(str)
476 {
477 while( *s )
478 {
479 if( *s != c )
480 {
481 *d++ = *s;
482 }
483 s++;
484 }
485 *d = 0;
486 }
487 }
488
489
490 gchar *hb_string_copy_jsonpair(gchar *dst, gchar *str)
491 {
492
493 while( *str!='\0' )
494 {
495 if( *str=='}' )
496 break;
497
498 if( *str==',' )
499 {
500 *dst = '\0';
501 return str + 1;
502 }
503
504 if( *str!='{' && *str!='\"' )
505 {
506 *dst++ = *str;
507 }
508 str++;
509 }
510 *dst = '\0';
511 return NULL;
512 }
513
514
515 void hb_string_inline(gchar *str)
516 {
517 gchar *s = str;
518 gchar *d = str;
519
520 if(str)
521 {
522 while( *s )
523 {
524 if( !(*s==' ' || *s=='\t' || *s=='\n' || *s=='\r') )
525 {
526 *d++ = *s;
527 }
528 s++;
529 }
530 *d = 0;
531 }
532 }
533
534
535 /*void strip_extra_spaces(char* str) {
536 int i,x;
537 for(i=x=1; str[i]; ++i)
538 if(!isspace(str[i]) || (i>0 && !isspace(str[i-1])))
539 str[x++] = str[i];
540 str[x] = '\0';
541 }*/
542
543
544
545 gchar*
546 hb_strdup_nobrackets (const gchar *str)
547 {
548 const gchar *s;
549 gchar *new_str, *d;
550 gsize length;
551
552 if (str)
553 {
554 length = strlen (str) + 1;
555 new_str = g_new (char, length);
556 s = str;
557 d = new_str;
558 while(*s != '\0')
559 {
560 if( *s != '[' && *s != ']' )
561 *d++ = *s;
562 s++;
563 }
564 *d = '\0';
565 }
566 else
567 new_str = NULL;
568
569 return new_str;
570 }
571
572
573 /* if we found a . or , within last x digits it might be a dchar */
574 static gchar hb_string_raw_amount_guess_dchar(const gchar *s, gint len, gshort digit)
575 {
576 gint nbc, nbd, i;
577 gchar gdc='?';
578
579 DB( g_print(" digit=%d maxidx=%d\n", digit, len-digit-1) );
580
581 nbc = nbd = 0;
582 for(i=len-1;i>=0;i--)
583 {
584 DB( g_print(" [%2d] '%c' %d %d '%c'\n", i, s[i], nbc, nbd, gdc) );
585 //store rightmost ,. within digit-1
586 if( i>=(len-digit-1) )
587 {
588 if(s[i]=='.' || s[i]==',')
589 gdc=s[i];
590 }
591 if(s[i]=='.') nbd++;
592 else if(s[i]==',') nbc++;
593 }
594 if( gdc=='.' && nbd > 1) gdc='?';
595 else if( gdc==',' && nbc > 1) gdc='?';
596
597 return gdc;
598 }
599
600
601 gchar *hb_string_dup_raw_amount_clean(const gchar *string, gint digits)
602 {
603 gint l;
604 gchar *new_str, *d;
605 gchar gdc;
606 const gchar *p = string;
607
608 l = strlen(string);
609 gdc = hb_string_raw_amount_guess_dchar(string, l, digits);
610
611 new_str = d = g_malloc (l+1);
612 while(*p)
613 {
614 if(*p=='-' || g_ascii_isdigit(*p) )
615 *d++ = *p;
616 else
617 if( *p==gdc )
618 {
619 *d++ = '.';
620 }
621 p++;
622 }
623 *d++ = '\0';
624
625 return new_str;
626 }
627
628
629 static gboolean
630 hb_date_parser_get_nums(gchar *string, gint *n1, gint *n2, gint *n3)
631 {
632 gboolean retval;
633 gchar **str_array;
634
635 //DB( g_print("(qif) hb_qif_parser_get_dmy for '%s'\n", string) );
636
637 retval = FALSE;
638 if( string )
639 {
640 str_array = g_strsplit (string, "/", 3);
641 if( g_strv_length( str_array ) != 3 )
642 {
643 g_strfreev (str_array);
644 str_array = g_strsplit (string, ".", 3);
645 // fix 371381
646 //todo test
647 if( g_strv_length( str_array ) != 3 )
648 {
649 g_strfreev (str_array);
650 str_array = g_strsplit (string, "-", 3);
651 }
652 }
653
654 if( g_strv_length( str_array ) == 3 )
655 {
656 *n1 = atoi(str_array[0]);
657 *n2 = atoi(str_array[1]);
658 *n3 = atoi(str_array[2]);
659 retval = TRUE;
660 }
661
662 g_strfreev (str_array);
663 }
664 return retval;
665 }
666
667
668 guint32 hb_date_get_julian(gchar *string, gint datefmt)
669 {
670 GDate *date;
671 gint n1, n2, n3, d, m, y;
672 guint32 julian = 0;
673
674 DB( g_print("\n[utils] hb_date_get_julian\n") );
675
676 DB( g_print(" - '%s' dateorder=%d\n", string, datefmt) );
677
678 if( hb_date_parser_get_nums(string, &n1, &n2, &n3) )
679 {
680 DB( g_print(" - '%d' '%d' '%d'\n", n1, n2, n3) );
681
682 switch(datefmt)
683 {
684 case PRF_DATEFMT_MDY:
685 d = n2;
686 m = n1;
687 y = n3;
688 break;
689 case PRF_DATEFMT_DMY:
690 d = n1;
691 m = n2;
692 y = n3;
693 break;
694 default:
695 case PRF_DATEFMT_YMD:
696 d = n3;
697 m = n2;
698 y = n1;
699 break;
700 }
701
702 //correct for 2 digits year
703 if(y < 1970)
704 {
705 if(y < 60)
706 y += 2000;
707 else
708 y += 1900;
709 }
710
711 if(d <= 31 && m <= 12)
712 {
713 if( g_date_valid_dmy(d, m, y) )
714 {
715 date = g_date_new_dmy(d, m, y);
716 julian = g_date_get_julian (date);
717 g_date_free(date);
718 }
719 }
720
721 DB( g_print(" > %d %d %d julian=%d\n", d, m, y, julian) );
722
723 }
724
725 return julian;
726 }
727
728
729 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
730
731 gint hb_filename_type_get_by_extension(gchar *filepath)
732 {
733 gint retval = FILETYPE_UNKNOWN;
734 gint str_len;
735
736 g_return_val_if_fail(filepath != NULL, FILETYPE_UNKNOWN);
737
738 str_len = strlen(filepath);
739 if( str_len >= 4 )
740 {
741 if( strcasecmp(filepath + str_len - 4, ".ofx") == 0)
742 retval = FILETYPE_OFX;
743 else
744 if( strcasecmp(filepath + str_len - 4, ".qif") == 0)
745 retval = FILETYPE_QIF;
746 else
747 if( strcasecmp(filepath + str_len - 4, ".qfx") == 0)
748 retval = FILETYPE_OFX;
749 else
750 if( strcasecmp(filepath + str_len - 4, ".csv") == 0)
751 retval = FILETYPE_CSV_HB;
752 else
753 if( strcasecmp(filepath + str_len - 4, ".xhb") == 0)
754 retval = FILETYPE_HOMEBANK;
755 }
756 return retval;
757 }
758
759
760 static gchar *hb_filename_new_without_extension(gchar *filename)
761 {
762 gchar *lastdot;
763
764 lastdot = g_strrstr (filename, ".");
765 if(lastdot != NULL)
766 {
767 return g_strndup(filename, strlen(filename) - strlen(lastdot));
768 }
769 return g_strdup(filename);
770 }
771
772
773 static gint hb_filename_backup_list_sort_func(gchar **a, gchar **b)
774 {
775 gint da = atoi( *a + strlen(*a) - 12);
776 gint db = atoi( *b + strlen(*b) - 12);
777
778 return db - da;
779 }
780
781
782 GPtrArray *hb_filename_backup_list(gchar *filename)
783 {
784 gchar *dirname, *basename;
785 gchar *rawfilename, *pattern;
786 GDir *dir;
787 const gchar *tmpname;
788 GPatternSpec *pspec;
789 GPtrArray *array;
790
791 DB( g_print("\n[util] filename backup list\n") );
792
793 dirname = g_path_get_dirname(filename);
794 basename = g_path_get_basename(filename);
795
796 DB( g_print(" dir='%s' base='%s'\n", dirname, basename) );
797
798 rawfilename = hb_filename_new_without_extension(basename);
799 pattern = g_strdup_printf("%s-????????.bak", rawfilename);
800
801 pspec = g_pattern_spec_new(pattern);
802
803
804 DB( g_print(" pattern='%s'\n", pattern) );
805
806 array = g_ptr_array_new_with_free_func(g_free);
807
808 dir = g_dir_open (PREFS->path_hbfile, 0, NULL);
809 if (dir)
810 {
811 while ((tmpname = g_dir_read_name (dir)) != NULL)
812 {
813 gboolean match;
814
815 match = g_pattern_match_string(pspec, tmpname);
816 if( match )
817 {
818 DB( g_print(" %d => '%s'\n", match, tmpname) );
819 g_ptr_array_add(array, g_strdup(tmpname));
820 }
821 }
822 }
823 g_free(pattern);
824 g_dir_close (dir);
825 g_pattern_spec_free(pspec);
826 g_free(rawfilename);
827
828 g_free(basename);
829 g_free(dirname);
830
831 g_ptr_array_sort(array, (GCompareFunc)hb_filename_backup_list_sort_func);
832
833 return array;
834 }
835
836
837 gchar *hb_filename_backup_get_filtername(gchar *filename)
838 {
839 gchar *dirname, *basename;
840 gchar *rawfilename, *pattern;
841
842 DB( g_print("\n[util] filename backup get filtername\n") );
843
844 dirname = g_path_get_dirname(filename);
845 basename = g_path_get_basename(filename);
846
847 DB( g_print(" dir='%s' base='%s'\n", dirname, basename) );
848
849 rawfilename = hb_filename_new_without_extension(basename);
850
851 pattern = g_strdup_printf("%s*.[Bb][Aa][Kk]", rawfilename);
852
853 g_free(rawfilename);
854 g_free(basename);
855 g_free(dirname);
856
857 return pattern;
858 }
859
860
861 gchar *hb_filename_new_for_backup(gchar *filename)
862 {
863 gchar *rawfilename, *newfilename;
864 GDate date;
865
866 DB( g_print("\n[util] filename new for backup\n") );
867
868 rawfilename = hb_filename_new_without_extension(filename);
869
870 g_date_clear(&date, 1);
871 g_date_set_julian (&date, GLOBALS->today);
872
873 newfilename = g_strdup_printf("%s-%04d%02d%02d.bak",
874 rawfilename,
875 g_date_get_year(&date),
876 g_date_get_month(&date),
877 g_date_get_day(&date)
878 );
879
880 g_free(rawfilename);
881
882 DB( g_print(" - '%s' => '%s'\n", filename, newfilename) );
883
884 return newfilename;
885 }
886
887
888 gchar *hb_filename_new_with_extension(gchar *filename, const gchar *extension)
889 {
890 gchar *rawfilename, *newfilename;
891
892 DB( g_print("\n[util] filename new with extension\n") );
893
894 rawfilename = hb_filename_new_without_extension(filename);
895 newfilename = g_strdup_printf("%s.%s", rawfilename, extension);
896 g_free(rawfilename);
897
898 DB( g_print(" - '%s' => '%s'\n", filename, newfilename) );
899
900 return newfilename;
901 }
902
903
904 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
905
906
907 gboolean hb_string_isdate(gchar *str)
908 {
909 gint d, m, y;
910
911 return(hb_date_parser_get_nums(str, &d, &m, &y));
912 }
913
914
915 gboolean hb_string_isdigit(gchar *str)
916 {
917 gboolean valid = TRUE;
918 while(*str && valid)
919 valid = g_ascii_isdigit(*str++);
920 return valid;
921 }
922
923 /*
924 gboolean hb_string_isprint(gchar *str)
925 {
926 gboolean valid = TRUE;
927 while(*str && valid)
928 valid = g_ascii_isprint(*str++);
929 return valid;
930 }
931 */
932
933
934
935 gboolean hb_string_isprint(gchar *str)
936 {
937 gboolean valid = TRUE;
938 gchar *p;
939 gunichar c;
940
941 if(g_utf8_validate(str, -1, NULL))
942 {
943 p = str;
944 while(*p && valid)
945 {
946 c = g_utf8_get_char(p);
947 valid = g_unichar_isprint(c);
948 p = g_utf8_next_char(p);
949 }
950 }
951 return valid;
952 }
953
954
955 gchar *hb_sprint_date(gchar *outstr, guint32 julian)
956 {
957 GDate date;
958
959 g_date_clear(&date, 1);
960 g_date_set_julian (&date, julian);
961 switch(PREFS->dtex_datefmt)
962 {
963 case PRF_DATEFMT_MDY:
964 {
965 g_sprintf(outstr, "%02d/%02d/%04d",
966 g_date_get_month(&date),
967 g_date_get_day(&date),
968 g_date_get_year(&date)
969 );
970 }
971 break;
972 case PRF_DATEFMT_DMY:
973 {
974 g_sprintf(outstr, "%02d/%02d/%04d",
975 g_date_get_day(&date),
976 g_date_get_month(&date),
977 g_date_get_year(&date)
978 );
979 }
980 break;
981 default:
982 g_sprintf(outstr, "%04d/%02d/%02d",
983 g_date_get_year(&date),
984 g_date_get_month(&date),
985 g_date_get_day(&date)
986 );
987 break;
988 }
989 return outstr;
990 }
991
992
993 //used only in DB() macro !!
994 void hb_print_date(guint32 jdate, gchar *label)
995 {
996 gchar buffer1[128];
997 GDate *date;
998
999 date = g_date_new_julian(jdate);
1000 g_date_strftime (buffer1, 128-1, "%x", date);
1001 g_date_free(date);
1002 g_print(" - %s %s\n", label != NULL ? label:"date is", buffer1);
1003 }
1004
1005
1006
1007 /*
1008 ** parse a string an retrieve an iso date (dd-mm-yy(yy) or dd/mm/yy(yy))
1009 **
1010 */
1011 /* obsolete 4.5
1012 guint32 hb_date_get_julian_parse(gchar *str)
1013 {
1014 gchar **str_array = NULL;
1015 GDate *date;
1016 guint d, m, y;
1017 guint32 julian = GLOBALS->today;
1018
1019 // try with - separator
1020 if( g_strrstr(str, "-") != NULL )
1021 {
1022 str_array = g_strsplit (str, "-", 3);
1023 }
1024 else
1025 {
1026 if( g_strrstr(str, "/") != NULL )
1027 {
1028 str_array = g_strsplit (str, "/", 3);
1029 }
1030 }
1031
1032 if( g_strv_length( str_array ) == 3 )
1033 {
1034 d = atoi(str_array[0]);
1035 m = atoi(str_array[1]);
1036 y = atoi(str_array[2]);
1037
1038 //correct for 2 digits year
1039 if(y < 1970)
1040 {
1041 if(y < 60)
1042 y += 2000;
1043 else
1044 y += 1900;
1045 }
1046
1047 //todo: here if month is > 12 then the format is probably mm/dd/yy(yy)
1048 //or maybe check with g_date_valid_julian(julian)
1049
1050
1051
1052 date = g_date_new();
1053 g_date_set_dmy(date, d, m, y);
1054 julian = g_date_get_julian (date);
1055 g_date_free(date);
1056
1057 DB( g_print("date: %s :: %d %d %d :: %d\n", str, d, m, y, julian ) );
1058
1059 }
1060
1061 g_strfreev (str_array);
1062
1063 return julian;
1064 }
1065 */
1066
1067 /* -------------------- */
1068
1069 #if MYDEBUG == 1
1070
1071 /*
1072 ** hex memory dump
1073 */
1074 #define MAX_DUMP 16
1075 void hex_dump(guchar *ptr, guint length)
1076 {
1077 guchar ascii[MAX_DUMP+4];
1078 guint i,j;
1079
1080 g_print("**hex_dump - %d bytes\n", length);
1081
1082 for(i=0;i<length;)
1083 {
1084 g_print("%08x: ", (guint)ptr+i);
1085
1086 for(j=0;j<MAX_DUMP;j++)
1087 {
1088 if(i >= length) break;
1089
1090 //store ascii value
1091 if(ptr[i] >= 32 && ptr[i] <= 126)
1092 ascii[j] = ptr[i];
1093 else
1094 ascii[j] = '.';
1095
1096 g_print("%02x ", ptr[i]);
1097 i++;
1098 }
1099 //newline
1100 ascii[j] = 0;
1101 g_print(" '%s'\n", ascii);
1102 }
1103 }
1104
1105 #endif
This page took 0.084368 seconds and 4 git commands to generate.