]> Dogcows Code - chaz/homebank/blob - src/hb-split.c
import homebank-5.2.4
[chaz/homebank] / src / hb-split.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 #include "homebank.h"
21
22 #include "hb-transaction.h"
23 #include "hb-split.h"
24
25 /****************************************************************************/
26 /* Debug macros */
27 /****************************************************************************/
28 #define MYDEBUG 0
29
30 #if MYDEBUG
31 #define DB(x) (x);
32 #else
33 #define DB(x);
34 #endif
35
36 /* our global datas */
37 extern struct HomeBank *GLOBALS;
38 extern struct Preferences *PREFS;
39
40
41 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
42
43
44 void da_split_free(Split *item)
45 {
46 if(item != NULL)
47 {
48 if(item->memo != NULL)
49 g_free(item->memo);
50
51 g_free(item);
52 }
53 }
54
55
56 Split *da_split_malloc(void)
57 {
58 return g_malloc0(sizeof(Split));
59 }
60
61
62 void da_split_destroy(GPtrArray *splits)
63 {
64 DB( g_print("da_split_destroy\n") );
65 if(splits != NULL)
66 g_ptr_array_free(splits, TRUE);
67 }
68
69
70 GPtrArray *da_split_new(void)
71 {
72 DB( g_print("da_split_new\n") );
73 return g_ptr_array_new_with_free_func((GDestroyNotify)da_split_free);
74 }
75
76
77 static GPtrArray *da_split_new_full(guint size)
78 {
79 DB( g_print("da_split_new\n") );
80 return g_ptr_array_new_full(size, (GDestroyNotify)da_split_free);
81 }
82
83
84 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
85
86 static gint da_splits_compare_func(gpointer a, gpointer b)
87 {
88 Split *sa = *(Split **)a;
89 Split *sb = *(Split **)b;
90
91 DB( g_print(" sort %d %s - %d %s\n", sa->pos, sa->memo, sb->pos, sb->memo) );
92
93 return sa->pos - sb->pos;
94 }
95
96 void da_splits_sort(GPtrArray *splits)
97 {
98 DB( g_print("da_splits_sort\n") );
99
100 if(splits == NULL)
101 {
102 //g_warning("NULL splits");
103 return;
104 }
105
106 g_ptr_array_sort(splits, (GCompareFunc) da_splits_compare_func);
107 }
108
109
110 guint da_splits_length(GPtrArray *splits)
111 {
112 DB( g_print("da_splits_length\n") );
113
114 if(splits == NULL)
115 {
116 //g_warning("NULL splits");
117 return 0;
118 }
119
120 return splits->len;
121 }
122
123
124 gboolean da_splits_remove(GPtrArray *splits, Split *item)
125 {
126 DB( g_print("da_splits_remove\n") );
127
128 if(splits == NULL)
129 {
130 g_warning("NULL splits");
131 return FALSE;
132 }
133
134 return g_ptr_array_remove(splits, item);
135 }
136
137
138 void da_splits_append(GPtrArray *splits, Split *item)
139 {
140 DB( g_print("da_splits_append\n") );
141
142 if(splits == NULL)
143 {
144 g_warning("NULL splits");
145 return;
146 }
147
148 if(splits->len <= TXN_MAX_SPLIT)
149 g_ptr_array_add (splits, item);
150 }
151
152
153 Split *da_splits_get(GPtrArray *splits, guint index)
154 {
155 return g_ptr_array_index(splits, index);
156 }
157
158
159 GPtrArray *da_splits_clone(GPtrArray *src_splits)
160 {
161 GPtrArray *new_splits;
162 guint i;
163
164 DB( g_print("da_splits_clone\n") );
165
166 if(src_splits == NULL)
167 {
168 //g_warning("NULL splits");
169 return NULL;
170 }
171
172 new_splits = da_split_new_full (src_splits->len);
173 for(i=0;i<src_splits->len;i++)
174 {
175 Split *src, *new;
176
177 src = g_ptr_array_index(src_splits, i);
178 new = da_split_malloc ();
179
180 new->kcat = src->kcat;
181 new->memo = g_strdup(src->memo);
182 new->amount = src->amount;
183 da_splits_append (new_splits, new);
184 }
185 return new_splits;
186 }
187
188
189 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
190
191
192 guint da_splits_parse(GPtrArray *splits, gchar *cats, gchar *amounts, gchar *memos)
193 {
194 gchar **cat_a, **amt_a, **mem_a;
195 guint count, i;
196 Split *split;
197
198 if(splits == NULL)
199 return 0;
200
201 DB( g_print(" split parse %s :: %s :: %s\n", cats, amounts, memos) );
202
203 cat_a = g_strsplit (cats, "||", 0);
204 amt_a = g_strsplit (amounts, "||", 0);
205 mem_a = g_strsplit (memos, "||", 0);
206
207 count = g_strv_length(amt_a);
208 if( (count == g_strv_length(cat_a)) && (count == g_strv_length(mem_a)) )
209 {
210 for(i=0;i<count;i++)
211 {
212 split = da_split_malloc();
213 split->kcat = atoi(cat_a[i]);
214 split->memo = g_strdup(mem_a[i]);
215 split->amount = g_ascii_strtod(amt_a[i], NULL);
216 da_splits_append (splits, split);
217 }
218 }
219 else
220 {
221 g_warning("invalid split parse");
222 }
223
224 g_strfreev (mem_a);
225 g_strfreev (amt_a);
226 g_strfreev (cat_a);
227
228 return count;
229 }
230
231
232 guint da_splits_tostring(GPtrArray *splits, gchar **cats, gchar **amounts, gchar **memos)
233 {
234 guint i;
235 Split *split;
236 char buf[G_ASCII_DTOSTR_BUF_SIZE];
237 GString *cat_a, *amt_a , *mem_a;
238
239 if(splits == NULL)
240 return 0;
241
242 DB( g_print(" splits tostring\n") );
243
244 cat_a = g_string_new (NULL);
245 amt_a = g_string_new (NULL);
246 mem_a = g_string_new (NULL);
247
248 for(i=0;i<splits->len;i++)
249 {
250 split = g_ptr_array_index(splits, i);
251 g_string_append_printf (cat_a, "%d", split->kcat);
252 g_string_append(amt_a, g_ascii_dtostr (buf, sizeof (buf), split->amount) );
253 g_string_append(mem_a, split->memo);
254
255 if((i+1) < splits->len)
256 {
257 g_string_append(cat_a, "||");
258 g_string_append(amt_a, "||");
259 g_string_append(mem_a, "||");
260 }
261 }
262
263 *cats = g_string_free(cat_a, FALSE);
264 *amounts = g_string_free(amt_a, FALSE);
265 *memos = g_string_free(mem_a, FALSE);
266
267 return i;
268 }
269
270
271 guint da_splits_consistency (GPtrArray *splits)
272 {
273 Split *split;
274 guint i;
275
276 if(splits == NULL)
277 return 0;
278
279 // check split category #1340142
280 for(i=0;i<splits->len;i++)
281 {
282 split = g_ptr_array_index(splits, i);
283 if(da_cat_get(split->kcat) == NULL)
284 {
285 g_warning("split consistency: fixed invalid split cat %d", split->kcat);
286 split->kcat = 0;
287 }
288 }
289 return splits->len;
290 }
291
This page took 0.042492 seconds and 4 git commands to generate.