]> Dogcows Code - chaz/homebank/blob - src/hb-misc.c
Merge branch 'upstream'
[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 static gboolean
574 hb_date_parser_get_nums(gchar *string, gint *n1, gint *n2, gint *n3)
575 {
576 gboolean retval;
577 gchar **str_array;
578
579 //DB( g_print("(qif) hb_qif_parser_get_dmy for '%s'\n", string) );
580
581 retval = FALSE;
582 if( string )
583 {
584 str_array = g_strsplit (string, "/", 3);
585 if( g_strv_length( str_array ) != 3 )
586 {
587 g_strfreev (str_array);
588 str_array = g_strsplit (string, ".", 3);
589 // fix 371381
590 //todo test
591 if( g_strv_length( str_array ) != 3 )
592 {
593 g_strfreev (str_array);
594 str_array = g_strsplit (string, "-", 3);
595 }
596 }
597
598 if( g_strv_length( str_array ) == 3 )
599 {
600 *n1 = atoi(str_array[0]);
601 *n2 = atoi(str_array[1]);
602 *n3 = atoi(str_array[2]);
603 retval = TRUE;
604 }
605
606 g_strfreev (str_array);
607 }
608 return retval;
609 }
610
611
612 guint32 hb_date_get_julian(gchar *string, gint datefmt)
613 {
614 GDate *date;
615 gint n1, n2, n3, d, m, y;
616 guint32 julian = 0;
617
618 DB( g_print("\n[utils] hb_date_get_julian\n") );
619
620 DB( g_print(" - '%s' dateorder=%d\n", string, datefmt) );
621
622 if( hb_date_parser_get_nums(string, &n1, &n2, &n3) )
623 {
624 DB( g_print(" - '%d' '%d' '%d'\n", n1, n2, n3) );
625
626 switch(datefmt)
627 {
628 case PRF_DATEFMT_MDY:
629 d = n2;
630 m = n1;
631 y = n3;
632 break;
633 case PRF_DATEFMT_DMY:
634 d = n1;
635 m = n2;
636 y = n3;
637 break;
638 default:
639 case PRF_DATEFMT_YMD:
640 d = n3;
641 m = n2;
642 y = n1;
643 break;
644 }
645
646 //correct for 2 digits year
647 if(y < 1970)
648 {
649 if(y < 60)
650 y += 2000;
651 else
652 y += 1900;
653 }
654
655 if(d <= 31 && m <= 12)
656 {
657 if( g_date_valid_dmy(d, m, y) )
658 {
659 date = g_date_new_dmy(d, m, y);
660 julian = g_date_get_julian (date);
661 g_date_free(date);
662 }
663 }
664
665 DB( g_print(" > %d %d %d julian=%d\n", d, m, y, julian) );
666
667 }
668
669 return julian;
670 }
671
672
673 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
674
675 gint hb_filename_type_get_by_extension(gchar *filepath)
676 {
677 gint retval = FILETYPE_UNKNOWN;
678 gint str_len;
679
680 g_return_val_if_fail(filepath != NULL, FILETYPE_UNKNOWN);
681
682 str_len = strlen(filepath);
683 if( str_len >= 4 )
684 {
685 if( strcasecmp(filepath + str_len - 4, ".ofx") == 0)
686 retval = FILETYPE_OFX;
687 else
688 if( strcasecmp(filepath + str_len - 4, ".qif") == 0)
689 retval = FILETYPE_QIF;
690 else
691 if( strcasecmp(filepath + str_len - 4, ".qfx") == 0)
692 retval = FILETYPE_OFX;
693 else
694 if( strcasecmp(filepath + str_len - 4, ".csv") == 0)
695 retval = FILETYPE_CSV_HB;
696 else
697 if( strcasecmp(filepath + str_len - 4, ".xhb") == 0)
698 retval = FILETYPE_HOMEBANK;
699 }
700 return retval;
701 }
702
703
704 static gchar *hb_filename_new_without_extension(gchar *filename)
705 {
706 gchar *lastdot;
707
708 lastdot = g_strrstr (filename, ".");
709 if(lastdot != NULL)
710 {
711 return g_strndup(filename, strlen(filename) - strlen(lastdot));
712 }
713 return g_strdup(filename);
714 }
715
716
717 static gint hb_filename_backup_list_sort_func(gchar **a, gchar **b)
718 {
719 gint da = atoi( *a + strlen(*a) - 12);
720 gint db = atoi( *b + strlen(*b) - 12);
721
722 return db - da;
723 }
724
725
726 GPtrArray *hb_filename_backup_list(gchar *filename)
727 {
728 gchar *dirname, *basename;
729 gchar *rawfilename, *pattern;
730 GDir *dir;
731 const gchar *tmpname;
732 GPatternSpec *pspec;
733 GPtrArray *array;
734
735 DB( g_print("\n[util] filename backup list\n") );
736
737 dirname = g_path_get_dirname(filename);
738 basename = g_path_get_basename(filename);
739
740 DB( g_print(" dir='%s' base='%s'\n", dirname, basename) );
741
742 rawfilename = hb_filename_new_without_extension(basename);
743 pattern = g_strdup_printf("%s-????????.bak", rawfilename);
744
745 pspec = g_pattern_spec_new(pattern);
746
747
748 DB( g_print(" pattern='%s'\n", pattern) );
749
750 array = g_ptr_array_new_with_free_func(g_free);
751
752 dir = g_dir_open (PREFS->path_hbfile, 0, NULL);
753 if (dir)
754 {
755 while ((tmpname = g_dir_read_name (dir)) != NULL)
756 {
757 gboolean match;
758
759 match = g_pattern_match_string(pspec, tmpname);
760 if( match )
761 {
762 DB( g_print(" %d => '%s'\n", match, tmpname) );
763 g_ptr_array_add(array, g_strdup(tmpname));
764 }
765 }
766 }
767 g_free(pattern);
768 g_dir_close (dir);
769 g_pattern_spec_free(pspec);
770 g_free(rawfilename);
771
772 g_free(basename);
773 g_free(dirname);
774
775 g_ptr_array_sort(array, (GCompareFunc)hb_filename_backup_list_sort_func);
776
777 return array;
778 }
779
780
781 gchar *hb_filename_backup_get_filtername(gchar *filename)
782 {
783 gchar *dirname, *basename;
784 gchar *rawfilename, *pattern;
785
786 DB( g_print("\n[util] filename backup get filtername\n") );
787
788 dirname = g_path_get_dirname(filename);
789 basename = g_path_get_basename(filename);
790
791 DB( g_print(" dir='%s' base='%s'\n", dirname, basename) );
792
793 rawfilename = hb_filename_new_without_extension(basename);
794
795 pattern = g_strdup_printf("%s*.[Bb][Aa][Kk]", rawfilename);
796
797 g_free(rawfilename);
798 g_free(basename);
799 g_free(dirname);
800
801 return pattern;
802 }
803
804
805 gchar *hb_filename_new_for_backup(gchar *filename)
806 {
807 gchar *rawfilename, *newfilename;
808 GDate date;
809
810 DB( g_print("\n[util] filename new for backup\n") );
811
812 rawfilename = hb_filename_new_without_extension(filename);
813
814 g_date_clear(&date, 1);
815 g_date_set_julian (&date, GLOBALS->today);
816
817 newfilename = g_strdup_printf("%s-%04d%02d%02d.bak",
818 rawfilename,
819 g_date_get_year(&date),
820 g_date_get_month(&date),
821 g_date_get_day(&date)
822 );
823
824 g_free(rawfilename);
825
826 DB( g_print(" - '%s' => '%s'\n", filename, newfilename) );
827
828 return newfilename;
829 }
830
831
832 gchar *hb_filename_new_with_extension(gchar *filename, const gchar *extension)
833 {
834 gchar *rawfilename, *newfilename;
835
836 DB( g_print("\n[util] filename new with extension\n") );
837
838 rawfilename = hb_filename_new_without_extension(filename);
839 newfilename = g_strdup_printf("%s.%s", rawfilename, extension);
840 g_free(rawfilename);
841
842 DB( g_print(" - '%s' => '%s'\n", filename, newfilename) );
843
844 return newfilename;
845 }
846
847
848 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
849
850
851 gboolean hb_string_isdate(gchar *str)
852 {
853 gint d, m, y;
854
855 return(hb_date_parser_get_nums(str, &d, &m, &y));
856 }
857
858
859 gboolean hb_string_isdigit(gchar *str)
860 {
861 gboolean valid = TRUE;
862 while(*str && valid)
863 valid = g_ascii_isdigit(*str++);
864 return valid;
865 }
866
867 /*
868 gboolean hb_string_isprint(gchar *str)
869 {
870 gboolean valid = TRUE;
871 while(*str && valid)
872 valid = g_ascii_isprint(*str++);
873 return valid;
874 }
875 */
876
877
878
879 gboolean hb_string_isprint(gchar *str)
880 {
881 gboolean valid = TRUE;
882 gchar *p;
883 gunichar c;
884
885 if(g_utf8_validate(str, -1, NULL))
886 {
887 p = str;
888 while(*p && valid)
889 {
890 c = g_utf8_get_char(p);
891 valid = g_unichar_isprint(c);
892 p = g_utf8_next_char(p);
893 }
894 }
895 return valid;
896 }
897
898
899 gchar *hb_sprint_date(gchar *outstr, guint32 julian)
900 {
901 GDate date;
902
903 g_date_clear(&date, 1);
904 g_date_set_julian (&date, julian);
905 switch(PREFS->dtex_datefmt)
906 {
907 case PRF_DATEFMT_MDY:
908 {
909 g_sprintf(outstr, "%02d/%02d/%04d",
910 g_date_get_month(&date),
911 g_date_get_day(&date),
912 g_date_get_year(&date)
913 );
914 }
915 break;
916 case PRF_DATEFMT_DMY:
917 {
918 g_sprintf(outstr, "%02d/%02d/%04d",
919 g_date_get_day(&date),
920 g_date_get_month(&date),
921 g_date_get_year(&date)
922 );
923 }
924 break;
925 default:
926 g_sprintf(outstr, "%04d/%02d/%02d",
927 g_date_get_year(&date),
928 g_date_get_month(&date),
929 g_date_get_day(&date)
930 );
931 break;
932 }
933 return outstr;
934 }
935
936
937 //used only in DB() macro !!
938 void hb_print_date(guint32 jdate, gchar *label)
939 {
940 gchar buffer1[128];
941 GDate *date;
942
943 date = g_date_new_julian(jdate);
944 g_date_strftime (buffer1, 128-1, "%x", date);
945 g_date_free(date);
946 g_print(" - %s %s\n", label != NULL ? label:"date is", buffer1);
947 }
948
949
950
951 /*
952 ** parse a string an retrieve an iso date (dd-mm-yy(yy) or dd/mm/yy(yy))
953 **
954 */
955 /* obsolete 4.5
956 guint32 hb_date_get_julian_parse(gchar *str)
957 {
958 gchar **str_array = NULL;
959 GDate *date;
960 guint d, m, y;
961 guint32 julian = GLOBALS->today;
962
963 // try with - separator
964 if( g_strrstr(str, "-") != NULL )
965 {
966 str_array = g_strsplit (str, "-", 3);
967 }
968 else
969 {
970 if( g_strrstr(str, "/") != NULL )
971 {
972 str_array = g_strsplit (str, "/", 3);
973 }
974 }
975
976 if( g_strv_length( str_array ) == 3 )
977 {
978 d = atoi(str_array[0]);
979 m = atoi(str_array[1]);
980 y = atoi(str_array[2]);
981
982 //correct for 2 digits year
983 if(y < 1970)
984 {
985 if(y < 60)
986 y += 2000;
987 else
988 y += 1900;
989 }
990
991 //todo: here if month is > 12 then the format is probably mm/dd/yy(yy)
992 //or maybe check with g_date_valid_julian(julian)
993
994
995
996 date = g_date_new();
997 g_date_set_dmy(date, d, m, y);
998 julian = g_date_get_julian (date);
999 g_date_free(date);
1000
1001 DB( g_print("date: %s :: %d %d %d :: %d\n", str, d, m, y, julian ) );
1002
1003 }
1004
1005 g_strfreev (str_array);
1006
1007 return julian;
1008 }
1009 */
1010
1011 /* -------------------- */
1012
1013 #if MYDEBUG == 1
1014
1015 /*
1016 ** hex memory dump
1017 */
1018 #define MAX_DUMP 16
1019 void hex_dump(guchar *ptr, guint length)
1020 {
1021 guchar ascii[MAX_DUMP+4];
1022 guint i,j;
1023
1024 g_print("**hex_dump - %d bytes\n", length);
1025
1026 for(i=0;i<length;)
1027 {
1028 g_print("%08x: ", (guint)ptr+i);
1029
1030 for(j=0;j<MAX_DUMP;j++)
1031 {
1032 if(i >= length) break;
1033
1034 //store ascii value
1035 if(ptr[i] >= 32 && ptr[i] <= 126)
1036 ascii[j] = ptr[i];
1037 else
1038 ascii[j] = '.';
1039
1040 g_print("%02x ", ptr[i]);
1041 i++;
1042 }
1043 //newline
1044 ascii[j] = 0;
1045 g_print(" '%s'\n", ascii);
1046 }
1047 }
1048
1049 #endif
This page took 0.082604 seconds and 4 git commands to generate.