diff options
| author | 2025-02-14 10:24:13 +0100 | |
|---|---|---|
| committer | 2025-02-14 10:24:13 +0100 | |
| commit | e020ca84718d99401a99af0363992b4661a1d16e (patch) | |
| tree | 9f980740c02571278be678630c84b85e19b6a979 /xs_po.h | |
| parent | html_footer() now receives an optional snac *user argument. (diff) | |
| download | penes-snac2-e020ca84718d99401a99af0363992b4661a1d16e.tar.gz penes-snac2-e020ca84718d99401a99af0363992b4661a1d16e.tar.xz penes-snac2-e020ca84718d99401a99af0363992b4661a1d16e.zip | |
xs_po.h new file.
Diffstat (limited to '')
| -rw-r--r-- | xs_po.h | 86 |
1 files changed, 86 insertions, 0 deletions
| @@ -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 | |||
| 7 | xs_dict *xs_po_to_dict(const char *fn); | ||
| 8 | |||
| 9 | #ifdef XS_IMPLEMENTATION | ||
| 10 | |||
| 11 | xs_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 */ | ||