payredu

Cross-platform ledger GUI written in c99
git clone git@getsh.org:payredu.git
Log | Files | Refs | README

account.c (2063B)


      1 #include <account.h>
      2 
      3 #include <stdlib.h>
      4 
      5 // TODO make this dynamic
      6 size_t tree_depth = 4;
      7 
      8 
      9 map_tree_t *account_search(map_tree_t *rootp, char *acc, size_t acc_size)
     10 {
     11 	assert(rootp != NULL);
     12 	// we hit leaf node, return rootp
     13 	if (rootp->children == NULL) return rootp;
     14 
     15 	//  return rootp when the 'acc' matches exactly with rootp->value
     16 	//  acc: this, rootp->value: this
     17 	vstr_t *rk = rootp->value;
     18 	if (rk != NULL && acc_size == rk->len && (strncmp(acc, rk->str, acc_size) == 0)) {
     19 		return rootp;
     20 	}
     21 
     22 	// search the string in it's children
     23 	for (size_t i = 0; i < rootp->children_len; i++) {
     24 		vstr_t *val = rootp->children[i].value;
     25 		if (val != NULL && acc_size == val->len && (strncmp(acc, val->str, acc_size) == 0)) {
     26 			return rootp->children + i;
     27 		}
     28 	}
     29 	return NULL;
     30 }
     31 
     32 int account_add(map_tree_t **rootp, char *acc, size_t acc_size)
     33 {
     34 	size_t records_needed = tree_depth * 4;
     35 	if (*rootp == NULL) {
     36 		*rootp = malloc(sizeof(map_tree_t));
     37 	}
     38 	if ((*rootp)->children == NULL) {
     39 		(*rootp)->children =
     40 			(map_tree_t *) calloc(records_needed, sizeof(map_tree_t));
     41 		(*rootp)->children_len = 0;
     42 		(*rootp)->children_cap = records_needed;
     43 	}
     44 	map_tree_t* _rootp = *rootp;
     45 	size_t i = 0;
     46 	while (i < acc_size) {
     47 		if (acc[i] == ':' || i + 1 == acc_size) {
     48 			size_t j = i + 1;
     49 			map_tree_t *current_node = account_search(_rootp, acc, j);
     50 			if (current_node == NULL) {
     51 				// return the previously allocated child
     52 				current_node = _rootp->children + _rootp->children_len++;
     53 				// current_node->value is NULL when the search fails
     54 				// we have to set the value now
     55 				// TODO maybe save vstrs in a pool and use them, would provide a sane way to free memory
     56 				vstr_t *vstr = (vstr_t *) malloc(sizeof(vstr_t));
     57 				vstr->str = acc;
     58 				vstr->len = j;
     59 				current_node->value = vstr;
     60 				//printf("%zu : %zu %d %.*s\n", current_node, vstr, j, j, acc);
     61 			} else {
     62 				//printf("Present already= %d %.*s\n", j, j, acc);
     63 			}
     64 			if (j != acc_size) {
     65 				return account_add(&current_node, acc + j,
     66 						acc_size - j);
     67 			}
     68 		}
     69 		i++;
     70 	}
     71 	return -1;
     72 }