diff options
Diffstat (limited to 'src/lang.c')
-rw-r--r-- | src/lang.c | 53 |
1 files changed, 44 insertions, 9 deletions
@@ -8,13 +8,13 @@ iDeclareType(Lang) | |||
8 | iDeclareType(MsgStr) | 8 | iDeclareType(MsgStr) |
9 | 9 | ||
10 | struct Impl_MsgStr { | 10 | struct Impl_MsgStr { |
11 | const char *id; /* these point to null-terminated strings in embedded data */ | 11 | iRangecc id; /* these point to null-terminated strings in embedded data */ |
12 | const char *str; | 12 | iRangecc str; |
13 | }; | 13 | }; |
14 | 14 | ||
15 | int cmp_MsgStr_(const void *e1, const void *e2) { | 15 | int cmp_MsgStr_(const void *e1, const void *e2) { |
16 | const iMsgStr *a = e1, *b = e2; | 16 | const iMsgStr *a = e1, *b = e2; |
17 | return iCmpStr(a->id, b->id); | 17 | return cmpCStrNSc_Rangecc(a->id, b->id.start, size_Range(&b->id), &iCaseSensitive); |
18 | } | 18 | } |
19 | 19 | ||
20 | /*----------------------------------------------------------------------------------------------*/ | 20 | /*----------------------------------------------------------------------------------------------*/ |
@@ -35,10 +35,12 @@ static void load_Lang_(iLang *d, const char *id) { | |||
35 | const iBlock *data = &blobEn_Embedded; | 35 | const iBlock *data = &blobEn_Embedded; |
36 | iMsgStr msg; | 36 | iMsgStr msg; |
37 | for (const char *ptr = constBegin_Block(data); ptr != constEnd_Block(data); ptr++) { | 37 | for (const char *ptr = constBegin_Block(data); ptr != constEnd_Block(data); ptr++) { |
38 | msg.id = ptr; | 38 | msg.id.start = ptr; |
39 | while (*++ptr) {} | 39 | while (*++ptr) {} |
40 | msg.str = ++ptr; | 40 | msg.id.end = ptr; |
41 | msg.str.start = ++ptr; | ||
41 | while (*++ptr) {} | 42 | while (*++ptr) {} |
43 | msg.str.end = ptr; | ||
42 | /* Allocate the string. The data has already been sorted. */ | 44 | /* Allocate the string. The data has already been sorted. */ |
43 | pushBack_Array(&d->messages->values, &msg); | 45 | pushBack_Array(&d->messages->values, &msg); |
44 | } | 46 | } |
@@ -62,18 +64,51 @@ void setCurrent_Lang(const char *language) { | |||
62 | load_Lang_(d, language); | 64 | load_Lang_(d, language); |
63 | } | 65 | } |
64 | 66 | ||
65 | const char *cstr_Lang(const char *msgId) { | 67 | iRangecc range_Lang(iRangecc msgId) { |
66 | const iLang *d = &lang_; | 68 | const iLang *d = &lang_; |
67 | size_t pos; | 69 | size_t pos; |
68 | const iMsgStr key = { .id = iConstCast(char *, msgId) }; | 70 | const iMsgStr key = { .id = msgId }; |
69 | if (locate_SortedArray(d->messages, &key, &pos)) { | 71 | if (locate_SortedArray(d->messages, &key, &pos)) { |
70 | return ((const iMsgStr *) at_SortedArray(d->messages, pos))->str; | 72 | return ((const iMsgStr *) at_SortedArray(d->messages, pos))->str; |
71 | } | 73 | } |
72 | fprintf(stderr, "[Lang] missing: %s\n", msgId); fflush(stderr); | 74 | fprintf(stderr, "[Lang] missing: %s\n", cstr_Rangecc(msgId)); fflush(stderr); |
73 | iAssert(iFalse); | 75 | iAssert(iFalse); |
74 | return msgId; | 76 | return msgId; |
75 | } | 77 | } |
76 | 78 | ||
79 | const char *cstr_Lang(const char *msgId) { | ||
80 | return range_Lang(range_CStr(msgId)).start; /* guaranteed to be NULL-terminated */ | ||
81 | } | ||
82 | |||
77 | const iString *string_Lang(const char *msgId) { | 83 | const iString *string_Lang(const char *msgId) { |
78 | return collectNewCStr_String(cstr_Lang(msgId)); | 84 | return collectNewRange_String(range_Lang(range_CStr(msgId))); |
85 | } | ||
86 | |||
87 | void translate_Lang(iString *textWithIds) { | ||
88 | for (const char *pos = cstr_String(textWithIds); *pos; ) { | ||
89 | iRangecc id; | ||
90 | id.start = strstr(pos, "${"); | ||
91 | if (!id.start) { | ||
92 | break; | ||
93 | } | ||
94 | id.start += 2; | ||
95 | id.end = strchr(id.start, '}'); | ||
96 | iAssert(id.end != NULL); | ||
97 | const size_t idLen = size_Range(&id); | ||
98 | const iRangecc replacement = range_Lang(id); | ||
99 | const size_t startPos = id.start - cstr_String(textWithIds) - 2; | ||
100 | /* Replace it. */ | ||
101 | remove_Block(&textWithIds->chars, startPos, idLen + 3); | ||
102 | insertData_Block(&textWithIds->chars, startPos, replacement.start, size_Range(&replacement)); | ||
103 | pos = cstr_String(textWithIds) + startPos + size_Range(&replacement); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | const char *translateCStr_Lang(const char *textWithIds) { | ||
108 | if (strstr(textWithIds, "${") == NULL) { | ||
109 | return textWithIds; /* nothing to replace */ | ||
110 | } | ||
111 | iString *text = collectNewCStr_String(textWithIds); | ||
112 | translate_Lang(text); | ||
113 | return cstr_String(text); | ||
79 | } | 114 | } |