po.h (4459B)
1 /* This program is licensed under the terms of GNU GPL v3 or (at your option) 2 * any later version. Copyright (C) 2021-2024 Страхиња Радић. 3 * See the file LICENSE for exact copyright and license details. */ 4 5 #include <stdint.h> 6 #include <stdlib.h> 7 8 #define MSGSTR_MAX 4096 9 #define ALLOC_DELTA 10 10 #define PO_DETECTION_LINES 24 11 /* If msgid/msgstr is longer, it will be saved as multiple lines */ 12 #define SAVE_MULTILINE_TRESHOLD 70 13 14 #define LOAD_PARSE_ERR(e) (LOAD_ERR_PARSE_PREFIX + (e)) 15 16 struct DrawState; 17 18 enum { 19 PARSE_ERR_NONE = 0, 20 PARSE_ERR_INVAL = 1, 21 PARSE_ERR_ALLOC = 2, 22 PARSE_ERR_SYNTAX = 3 23 }; 24 25 enum { 26 LOAD_ERR_NONE = 0, 27 LOAD_ERR_CANT_ALLOC = 1, 28 LOAD_ERR_CANT_OPEN_FILE = 2, 29 LOAD_ERR_NOT_PO_FILE = 3, 30 LOAD_ERR_PARSE_PREFIX = 100, 31 LOAD_ERR_P_INVAL = LOAD_PARSE_ERR(PARSE_ERR_INVAL), 32 LOAD_ERR_P_ALLOC = LOAD_PARSE_ERR(PARSE_ERR_ALLOC), 33 LOAD_ERR_P_SYNTAX = LOAD_PARSE_ERR(PARSE_ERR_SYNTAX) 34 }; 35 36 enum { 37 SAVE_ERR_NONE = 0, 38 SAVE_ERR_CANT_ALLOC = 1, 39 SAVE_ERR_CANT_OPEN_FILE = 2, 40 SAVE_ERR_CANT_MOVE_FILE = 3, 41 SAVE_ERR_CANT_STAT_FILE = 4, 42 SAVE_ERR_CANT_READLINK = 5, 43 SAVE_ERR_CANT_SYMLINK = 6, 44 SAVE_ERR_CANT_UNLINK = 7 45 }; 46 47 typedef enum { 48 PS_NONE = 0, 49 PS_COMMENT_TRAN = 1, /* "translator-comments" : # */ 50 PS_COMMENT_EXTR = 1 << 1, /* "extracted-comments" : #. */ 51 PS_COMMENT_FLAG = 1 << 2, /* "flag" : #, */ 52 PS_COMMENT_REFN = 1 << 3, /* "reference" : #: */ 53 PS_COMMENT_OBSO = 1 << 4, /* obsolete (undocumented) : #~ */ 54 PS_MSGID = 1 << 5, 55 PS_MSGID_PLURAL = 1 << 6, 56 PS_MSGSTR = 1 << 7, 57 PS_MSGSTR_ARRAY = 1 << 8 58 } ParseState; 59 60 /* Complete list at: 61 * 62 * https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html 63 * 64 * - JS, awk and sh using gettext, seriously? 65 * "Let's just shove every programming and scripting language there is into 66 * flags!" /s 67 * Where are the flags for Pascal and Ada, by the way, hmm? [SR] 68 * 69 * - Including just the sane values, will strip the rest. */ 70 typedef enum { 71 FL_NONE = 0, 72 FL_FUZZY = 1, 73 FL_C_FORMAT = 1 << 1, 74 FL_NO_C_FORMAT = 1 << 2 75 } Flags; 76 77 struct PoEntry { 78 Flags flags; 79 int obsolete; 80 int warning; 81 uint32_t* msgid; 82 size_t msgid_size; 83 size_t msgid_len; 84 uint32_t* msgid_plural; 85 size_t msgid_plural_size; 86 size_t msgid_plural_len; 87 uint32_t* plural_forms; 88 uint32_t** msgstr; 89 int msgstr_count; 90 size_t* msgstr_size; 91 size_t* msgstr_len; 92 uint32_t** comments; 93 size_t comment_lines; 94 uint32_t** trans_comments; 95 size_t trans_comment_lines; 96 char** ref_comments; 97 size_t ref_comment_lines; 98 }; 99 100 char* format_flags(char* buffer, const size_t max, const struct PoEntry* entry, 101 const int draw_box); 102 void init_po_entry(struct PoEntry* entry); 103 void free_po_entry(struct PoEntry* entry); 104 struct PoEntry* set_flags(struct PoEntry* entry, const Flags flags); 105 struct PoEntry* set_msgid(struct PoEntry* entry, const char* msgid, int append); 106 struct PoEntry* set_msgid_plural(struct PoEntry* entry, 107 const char* msgid_plural, int append); 108 struct PoEntry* set_plural_forms(struct PoEntry* entry, 109 const char* plural_forms, int append); 110 struct PoEntry* set_msgstr(struct PoEntry* entry, const char* msgstr, 111 int msgstr_index, int append, struct DrawState* state); 112 struct PoEntry* u32_set_msgid(struct PoEntry* entry, const uint32_t* msgid, 113 size_t msgid_size, int append); 114 struct PoEntry* u32_set_msgid_plural(struct PoEntry* entry, 115 const uint32_t* msgid_plural, size_t msgid_plural_size, int append); 116 struct PoEntry* u32_set_plural_forms(struct PoEntry* entry, 117 const uint32_t* plural_forms, int append); 118 struct PoEntry* u32_set_msgstr(struct PoEntry* entry, const uint32_t* msgstr, 119 int msgstr_index, int append, struct DrawState* state); 120 struct PoEntry* u32_add_comment(struct PoEntry* entry, const uint32_t* comment); 121 struct PoEntry* u32_add_trans_comment(struct PoEntry* entry, 122 const uint32_t* trans_comment); 123 struct PoEntry* add_ref_comment(struct PoEntry* entry, const char* comment); 124 int load_file(struct DrawState* state, long* lineno, long* col); 125 int save_file(const struct PoEntry* entries, const size_t real_msgid_count, 126 const char* filename, const int nplurals); 127 int parse_po_line(const char* line, struct DrawState* dstate, 128 struct PoEntry** current_entry, ParseState* pstate, long* col, 129 int* msgstr_index); 130 void update_statistics(const struct PoEntry* entries, struct DrawState* state, 131 struct PoEntry* entry); 132 void update_warning(const uint32_t* msgid, const uint32_t* msgstr, int* warning);