summaryrefslogtreecommitdiff
path: root/xs_po.h
diff options
context:
space:
mode:
authorGravatar default2025-02-14 10:24:13 +0100
committerGravatar default2025-02-14 10:24:13 +0100
commite020ca84718d99401a99af0363992b4661a1d16e (patch)
tree9f980740c02571278be678630c84b85e19b6a979 /xs_po.h
parenthtml_footer() now receives an optional snac *user argument. (diff)
downloadsnac2-e020ca84718d99401a99af0363992b4661a1d16e.tar.gz
snac2-e020ca84718d99401a99af0363992b4661a1d16e.tar.xz
snac2-e020ca84718d99401a99af0363992b4661a1d16e.zip
xs_po.h new file.
Diffstat (limited to 'xs_po.h')
-rw-r--r--xs_po.h86
1 files changed, 86 insertions, 0 deletions
diff --git a/xs_po.h b/xs_po.h
new file mode 100644
index 0000000..c6feec9
--- /dev/null
+++ b/xs_po.h
@@ -0,0 +1,86 @@
1/* copyright (c) 2025 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 */