42 #define NULLSEP_STR "\xff"
43 #define NULLSEP_CHR '\xff'
62 const size_t len = strlen(
str);
69 for (i = 0; i <
len &&
ELEM(
str[0],
' ',
'\t',
'\r',
'\n');
str++, i++) {
73 char *end = &
str[
len - 1 - i];
74 for (i =
len; i > 0 &&
ELEM(end[0],
' ',
'\t',
'\r',
'\n'); end--, i--) {
87 if (
next[0] ==
'\\') {
111 else if (curr !=
next) {
117 if (
str[0] ==
'"' && *(curr - 1) ==
'"') {
126 return strcmp(*(
const char **)
a, *(
const char **)
b);
133 char **keys =
MEM_mallocN(
sizeof(*keys) * num_keys, __func__);
149 for (i = 0; i <
sizeof(value); i++) {
150 bytes[i] = (char)((value >> ((
int)i * 8)) & 0xff);
159 for (i = 0; i <
size; i++, msg++, bytes++) {
176 char **vals =
MEM_mallocN(
sizeof(*vals) * num_keys, __func__);
182 for (
int i = 0; i < num_keys; i++) {
183 Offset *off = &offsets[i];
191 tot_keys_len += off->
key_len + 1;
195 tot_vals_len += off->
val_len + 1;
200 const uint32_t idx_keystart = 7 * 4;
201 const uint32_t idx_valstart = idx_keystart + 8 * num_keys;
203 const uint32_t keystart = idx_valstart + 8 * num_keys;
205 const uint32_t valstart = keystart + tot_keys_len;
208 *r_output_size = valstart + tot_vals_len;
211 char *ik =
output + idx_keystart;
212 char *iv =
output + idx_valstart;
213 char *k =
output + keystart;
226 for (
int i = 0; i < num_keys; i++) {
227 Offset *off = &offsets[i];
257 const size_t msgkey_len = msgid_len + ((msgctxt_len == 0) ? 0 : msgctxt_len + 1);
259 if (!msg->
is_fuzzy && msgstr_len != 0) {
263 if (msgctxt_len != 0) {
265 msgkey[msgctxt_len] =
'\x04';
286 static int make(
const char *input_file_name,
const char *output_file_name)
291 const char *msgctxt_kw =
"msgctxt";
292 const char *msgid_kw =
"msgid";
293 const char *msgid_plural_kw =
"msgid_plural";
294 const char *msgstr_kw =
"msgstr";
295 const size_t msgctxt_len = strlen(msgctxt_kw);
296 const size_t msgid_len = strlen(msgid_kw);
297 const size_t msgid_plural_len = strlen(msgid_plural_kw);
298 const size_t msgstr_len = strlen(msgstr_kw);
303 bool is_plural =
false;
316 for (
int lno = 1; ifl; ifl = ifl->
next, lno++) {
318 const bool is_comment = (
l[0] ==
'#');
322 add(messages, msgs_memarena, &msg);
327 if (
l[1] ==
',' && strstr(
l,
"fuzzy") !=
NULL) {
333 if (strstr(
l, msgctxt_kw) ==
l) {
336 add(messages, msgs_memarena, &msg);
339 printf(
"msgctxt not at start of new message on %s:%d\n", input_file_name, lno);
346 else if (strstr(
l, msgid_plural_kw) ==
l) {
349 printf(
"msgid_plural not preceded by msgid on %s:%d\n", input_file_name, lno);
352 l =
l + msgid_plural_len;
356 else if (strstr(
l, msgid_kw) ==
l) {
358 add(messages, msgs_memarena, &msg);
367 else if (strstr(
l, msgstr_kw) ==
l) {
373 printf(
"plural without msgid_plural on %s:%d\n", input_file_name, lno);
376 if ((
l = strchr(
l,
']')) ==
NULL) {
377 printf(
"Syntax error on %s:%d\n", input_file_name, lno);
386 printf(
"indexed msgstr required for plural on %s:%d\n", input_file_name, lno);
395 add(messages, msgs_memarena, &msg);
412 printf(
"Syntax error on %s:%d\n", input_file_name, lno);
418 add(messages, msgs_memarena, &msg);
430 FILE *fp =
BLI_fopen(output_file_name,
"wb");
431 fwrite(
output, 1, output_size, fp);
441 int main(
int argc,
char **argv)
444 printf(
"Usage: %s <input.po> <output.mo>\n", argv[0]);
447 const char *input_file = argv[1];
448 const char *output_file = argv[2];
450 return make(input_file, output_file);
A dynamically sized string ADT.
int BLI_dynstr_get_len(const 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(const DynStr *__restrict ds, char *__restrict rets) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
File and directory operations.
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_file_free_lines(struct LinkNode *lines)
struct LinkNode * BLI_file_read_as_lines(const char *file) 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
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghash_len(const 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_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#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)
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)
ccl_global KernelShaderEvalInput ccl_global float * output
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)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)