diff options
| author | default <nobody@localhost> | 2025-02-14 10:24:13 +0100 |
|---|---|---|
| committer | default <nobody@localhost> | 2025-02-14 10:24:13 +0100 |
| commit | e020ca84718d99401a99af0363992b4661a1d16e (patch) | |
| tree | 9f980740c02571278be678630c84b85e19b6a979 /xs_po.h | |
| parent | 78bd0263ce56ce8d8544389971daa3d6cdd5c25e (diff) | |
xs_po.h new file.
Diffstat (limited to 'xs_po.h')
| -rw-r--r-- | xs_po.h | 86 |
1 files changed, 86 insertions, 0 deletions
@@ -0,0 +1,86 @@ +/* copyright (c) 2025 grunfink et al. / MIT license */ + +#ifndef _XS_PO_H + +#define _XS_PO_H + +xs_dict *xs_po_to_dict(const char *fn); + +#ifdef XS_IMPLEMENTATION + +xs_dict *xs_po_to_dict(const char *fn) +/* converts a PO file to a dict */ +{ + xs_dict *d = NULL; + FILE *f; + + if ((f = fopen(fn, "r")) != NULL) { + d = xs_dict_new(); + + xs *k = NULL; + xs *v = NULL; + enum { IN_NONE, IN_K, IN_V } mode = IN_NONE; + + while (!feof(f)) { + xs *l = xs_strip_i(xs_readline(f)); + + /* discard empty lines and comments */ + if (*l == '\0' || *l == '#') + continue; + + if (xs_startswith(l, "msgid ")) { + if (mode == IN_V) { + /* flush */ + if (xs_is_string(k) && xs_is_string(v) && *v) + d = xs_dict_set(d, k, v); + + k = xs_free(k); + v = xs_free(v); + } + + l = xs_replace_i(l, "msgid ", ""); + mode = IN_K; + + k = xs_str_new(NULL); + } + else + if (xs_startswith(l, "msgstr ")) { + if (mode != IN_K) + break; + + l = xs_replace_i(l, "msgstr ", ""); + mode = IN_V; + + v = xs_str_new(NULL); + } + + l = xs_replace_i(l, "\\n", "\n"); + l = xs_strip_chars_i(l, "\""); + + switch (mode) { + case IN_K: + k = xs_str_cat(k, l); + break; + + case IN_V: + v = xs_str_cat(v, l); + break; + + case IN_NONE: + break; + } + } + + /* final flush */ + if (xs_is_string(k) && xs_is_string(v) && *v) + d = xs_dict_set(d, k, v); + + fclose(f); + } + + return d; +} + +#endif /* XS_IMPLEMENTATION */ + +#endif /* XS_PO_H */ |