2.92 xs_po.h
 1/* copyright (c) 2025 - 2026 grunfink et al. / MIT license */
 2
 3#ifndef _XS_PO_H
 4
 5#define _XS_PO_H
 6
 7xs_dict *xs_po_to_dict(const char *fn);
 8
 9#ifdef XS_IMPLEMENTATION
10
11xs_dict *xs_po_to_dict(const char *fn)
12/* converts a PO file to a dict */
13{
14    xs_dict *d = NULL;
15    FILE *f;
16
17    if ((f = fopen(fn, "r")) != NULL) {
18        d = xs_dict_new();
19
20        xs *k = NULL;
21        xs *v = NULL;
22        enum { IN_NONE, IN_K, IN_V } mode = IN_NONE;
23
24        while (!feof(f)) {
25            xs *l = xs_strip_i(xs_readline(f));
26
27            /* discard empty lines and comments */
28            if (*l == '\0' || *l == '#')
29                continue;
30
31            if (xs_startswith(l, "msgid ")) {
32                if (mode == IN_V) {
33                    /* flush */
34                    if (xs_is_string(k) && xs_is_string(v) && *v)
35                        d = xs_dict_set(d, k, v);
36
37                    k = xs_free(k);
38                    v = xs_free(v);
39                }
40
41                l = xs_replace_i(l, "msgid ", "");
42                mode = IN_K;
43
44                k = xs_str_new(NULL);
45            }
46            else
47            if (xs_startswith(l, "msgstr ")) {
48                if (mode != IN_K)
49                    break;
50
51                l = xs_replace_i(l, "msgstr ", "");
52                mode = IN_V;
53
54                v = xs_str_new(NULL);
55            }
56
57            l = xs_replace_i(l, "\\n", "\n");
58            l = xs_strip_chars_i(l, "\"");
59
60            switch (mode) {
61            case IN_K:
62                k = xs_str_cat(k, l);
63                break;
64
65            case IN_V:
66                v = xs_str_cat(v, l);
67                break;
68
69            case IN_NONE:
70                break;
71            }
72        }
73
74        /* final flush */
75        if (xs_is_string(k) && xs_is_string(v) && *v)
76            d = xs_dict_set(d, k, v);
77
78        fclose(f);
79    }
80
81    return d;
82}
83
84#endif /* XS_IMPLEMENTATION */
85
86#endif /* XS_PO_H */