58 #define NULLSEP_STR "\xff"
59 #define NULLSEP_CHR '\xff'
78 const size_t len = strlen(
str);
85 for (i = 0; i <
len &&
ELEM(
str[0],
' ',
'\t',
'\r',
'\n');
str++, i++) {
89 char *end = &
str[
len - 1 - i];
90 for (i =
len; i > 0 &&
ELEM(end[0],
' ',
'\t',
'\r',
'\n'); end--, i--) {
103 if (
next[0] ==
'\\') {
127 else if (curr !=
next) {
133 if (
str[0] ==
'"' && *(curr - 1) ==
'"') {
142 return strcmp(*(
const char **)
a, *(
const char **)b);
149 char **keys =
MEM_mallocN(
sizeof(*keys) * num_keys, __func__);
165 for (i = 0; i <
sizeof(value); i++) {
166 bytes[i] = (char)((value >> ((
int)i * 8)) & 0xff);
175 for (i = 0; i <
size; i++, msg++, bytes++) {
192 char **vals =
MEM_mallocN(
sizeof(*vals) * num_keys, __func__);
198 for (
int i = 0; i < num_keys; i++) {
199 Offset *off = &offsets[i];
207 tot_keys_len += off->
key_len + 1;
211 tot_vals_len += off->
val_len + 1;
216 const uint32_t idx_keystart = 7 * 4;
217 const uint32_t idx_valstart = idx_keystart + 8 * num_keys;
219 const uint32_t keystart = idx_valstart + 8 * num_keys;
221 const uint32_t valstart = keystart + tot_keys_len;
224 *r_output_size = valstart + tot_vals_len;
227 char *ik =
output + idx_keystart;
228 char *iv =
output + idx_valstart;
229 char *k =
output + keystart;
242 for (
int i = 0; i < num_keys; i++) {
243 Offset *off = &offsets[i];
273 const size_t msgkey_len = msgid_len + ((msgctxt_len == 0) ? 0 : msgctxt_len + 1);
275 if (!msg->
is_fuzzy && msgstr_len != 0) {
279 if (msgctxt_len != 0) {
281 msgkey[msgctxt_len] =
'\x04';
302 static int make(
const char *input_file_name,
const char *output_file_name)
307 const char *msgctxt_kw =
"msgctxt";
308 const char *msgid_kw =
"msgid";
309 const char *msgid_plural_kw =
"msgid_plural";
310 const char *msgstr_kw =
"msgstr";
311 const size_t msgctxt_len = strlen(msgctxt_kw);
312 const size_t msgid_len = strlen(msgid_kw);
313 const size_t msgid_plural_len = strlen(msgid_plural_kw);
314 const size_t msgstr_len = strlen(msgstr_kw);
319 bool is_plural =
false;
332 for (
int lno = 1; ifl; ifl = ifl->
next, lno++) {
334 const bool is_comment = (
l[0] ==
'#');
338 add(messages, msgs_memarena, &msg);
343 if (
l[1] ==
',' && strstr(
l,
"fuzzy") !=
NULL) {
349 if (strstr(
l, msgctxt_kw) ==
l) {
352 add(messages, msgs_memarena, &msg);
355 printf(
"msgctxt not at start of new message on %s:%d\n", input_file_name, lno);
362 else if (strstr(
l, msgid_plural_kw) ==
l) {
365 printf(
"msgid_plural not preceded by msgid on %s:%d\n", input_file_name, lno);
368 l =
l + msgid_plural_len;
372 else if (strstr(
l, msgid_kw) ==
l) {
374 add(messages, msgs_memarena, &msg);
383 else if (strstr(
l, msgstr_kw) ==
l) {
389 printf(
"plural without msgid_plural on %s:%d\n", input_file_name, lno);
392 if ((
l = strchr(
l,
']')) ==
NULL) {
393 printf(
"Syntax error on %s:%d\n", input_file_name, lno);
402 printf(
"indexed msgstr required for plural on %s:%d\n", input_file_name, lno);
411 add(messages, msgs_memarena, &msg);
428 printf(
"Syntax error on %s:%d\n", input_file_name, lno);
434 add(messages, msgs_memarena, &msg);
446 FILE *fp =
BLI_fopen(output_file_name,
"wb");
447 fwrite(
output, 1, output_size, fp);
457 int main(
int argc,
char **argv)
460 printf(
"Usage: %s <input.po> <output.mo>\n", argv[0]);
463 const char *input_file = argv[1];
464 const char *output_file = argv[2];
466 return make(input_file, output_file);
A dynamically sized string ADT.
int BLI_dynstr_get_len(DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_dynstr_clear(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
DynStr * BLI_dynstr_new_memarena(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_get_cstring_ex(DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
File and directory operations.
void BLI_file_free_lines(struct LinkNode *lines)
struct LinkNode * BLI_file_read_as_lines(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
FILE * BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_ghashutil_strcmp(const void *a, const void *b)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER(gh_iter_, ghash_)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghash_len(GHash *gh) ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghashutil_strhash_p_murmur(const void *ptr)
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
#define BLI_MEMARENA_STD_BUFSIZE
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)
static char * generate(GHash *messages, size_t *r_output_size)
BLI_INLINE size_t uint32_to_bytes(const int value, char *bytes)
static int make(const char *input_file_name, const char *output_file_name)
int main(int argc, char **argv)
static char * unescape(char *str)
static void clear(Message *msg)
static char ** get_keys_sorted(GHash *messages, const uint32_t num_keys)
static int qsort_str_cmp(const void *a, const void *b)
static char * trim(char *str)
static void add(GHash *messages, MemArena *memarena, const Message *msg)
BLI_INLINE size_t msg_to_bytes(char *msg, char *bytes, uint32_t size)