aboutsummaryrefslogtreecommitdiff
path: root/src/formula.h
blob: f8476d0f053575518287cd457e69d6e124ed187d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef BOKF_FORMULA_H
#define BOKF_FORMULA_H

#include <stddef.h>
#include <stdint.h>

/* Tiny, deterministic expression evaluator for voucher templates.
   Grammar:  expr := term (('+'|'-') term)*
             term := factor (('*'|'/') factor)*
             factor := ('+'|'-') factor | primary
             primary := number | 'x' | '(' expr ')'
   Values are kronor as double; x is the template variable in kronor. */

struct template_row {
    const char *account;     /* account number */
    const char *formula;
    const char *description; /* optional */
};

struct resolved_row {
    char account[16];
    int64_t debit_ore;
    int64_t credit_ore;
    char description[128];
};

/* Returns 0 on success and stores the value in *out_kr. On error returns
   -1 and writes a message to errbuf. */
int formula_eval(const char *formula, double x, double *out_kr, char *errbuf,
                 size_t errlen);

/* Evaluates all rows with x, rounds to whole öre, drops zero rows, and
   assigns the rounding remainder to the largest row so debit equals credit.
   Returns 0 on success and sets *out_n. Errors (bad formula, too few
   rows) are reported in errbuf. */
int formula_resolve_rows(const struct template_row *rows, size_t nrows,
                         double x, struct resolved_row *out, size_t *out_n,
                         char *errbuf, size_t errlen);

/* True when the formula parses (evaluated with x = 1). */
int formula_valid(const char *formula);

#endif