snac2

Fork of https://codeberg.org/grunfink/snac2
git clone https://git.inz.fi/snac2
Log | Files | Refs | README | LICENSE

xs_po.h (1926B)


      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 */