summaryrefslogtreecommitdiff
path: root/src/lang.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lang.c')
-rw-r--r--src/lang.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/lang.c b/src/lang.c
index be8ad9d1..983ae3c5 100644
--- a/src/lang.c
+++ b/src/lang.c
@@ -19,12 +19,32 @@ int cmp_MsgStr_(const void *e1, const void *e2) {
19 19
20/*----------------------------------------------------------------------------------------------*/ 20/*----------------------------------------------------------------------------------------------*/
21 21
22enum iPluralType {
23 none_PluralType,
24 notEqualToOne_PluralType,
25 slavic_PluralType,
26};
27
22struct Impl_Lang { 28struct Impl_Lang {
23 iSortedArray *messages; 29 iSortedArray *messages;
30 enum iPluralType pluralType;
24}; 31};
25 32
26static iLang lang_; 33static iLang lang_;
27 34
35static size_t pluralIndex_Lang_(const iLang *d, int n) {
36 switch (d->pluralType) {
37 case notEqualToOne_PluralType:
38 return n != 1;
39 case slavic_PluralType:
40 return n % 10 == 1 && n % 100 != 11 ? 0
41 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1
42 : 2;
43 default:
44 return 0;
45 }
46}
47
28static void clear_Lang_(iLang *d) { 48static void clear_Lang_(iLang *d) {
29 clear_SortedArray(d->messages); 49 clear_SortedArray(d->messages);
30} 50}
@@ -36,6 +56,15 @@ static void load_Lang_(iLang *d, const char *id) {
36 : equal_CStr(id, "ru") ? &blobRu_Embedded 56 : equal_CStr(id, "ru") ? &blobRu_Embedded
37 : equal_CStr(id, "de") ? &blobDe_Embedded 57 : equal_CStr(id, "de") ? &blobDe_Embedded
38 : &blobEn_Embedded; 58 : &blobEn_Embedded;
59 if (data == &blobRu_Embedded) {
60 d->pluralType = slavic_PluralType;
61 }
62// else if (data == &blobZhHans_Embedded) {
63// d->pluralType = none_PluralType;
64// }
65 else {
66 d->pluralType = notEqualToOne_PluralType;
67 }
39 iMsgStr msg; 68 iMsgStr msg;
40 for (const char *ptr = constBegin_Block(data); ptr != constEnd_Block(data); ptr++) { 69 for (const char *ptr = constBegin_Block(data); ptr != constEnd_Block(data); ptr++) {
41 msg.id.start = ptr; 70 msg.id.start = ptr;
@@ -45,6 +74,7 @@ static void load_Lang_(iLang *d, const char *id) {
45 while (*++ptr) {} 74 while (*++ptr) {}
46 msg.str.end = ptr; 75 msg.str.end = ptr;
47 /* Allocate the string. The data has already been sorted. */ 76 /* Allocate the string. The data has already been sorted. */
77 printf("ID:%s\n", msg.id.start);
48 pushBack_Array(&d->messages->values, &msg); 78 pushBack_Array(&d->messages->values, &msg);
49 } 79 }
50} 80}
@@ -87,12 +117,30 @@ iRangecc range_Lang(iRangecc msgId) {
87 return str; 117 return str;
88} 118}
89 119
120const iString *string_Lang(const char *msgId) {
121 return collectNewRange_String(range_Lang(range_CStr(msgId)));
122}
123
90const char *cstr_Lang(const char *msgId) { 124const char *cstr_Lang(const char *msgId) {
91 return range_Lang(range_CStr(msgId)).start; /* guaranteed to be NULL-terminated */ 125 return range_Lang(range_CStr(msgId)).start; /* guaranteed to be NULL-terminated */
92} 126}
93 127
94const iString *string_Lang(const char *msgId) { 128static char *pluralId_Lang_(const iLang *d, const char *msgId, int count) {
95 return collectNewRange_String(range_Lang(range_CStr(msgId))); 129 const size_t len = strlen(msgId);
130 char *pluralId = strdup(msgId);
131 pluralId[len - 1] = '0' + pluralIndex_Lang_(d, count);
132 return pluralId;
133}
134
135const char *cstrCount_Lang(const char *msgId, int count) {
136 iAssert(endsWith_Rangecc(range_CStr(msgId), ".n")); /* by convention */
137 char *pluralId = pluralId_Lang_(&lang_, msgId, count);
138 const char *str = cstr_Lang(pluralId);
139 if (str == pluralId) {
140 str = msgId; /* not found */
141 }
142 free(pluralId);
143 return str;
96} 144}
97 145
98void translate_Lang(iString *textWithIds) { 146void translate_Lang(iString *textWithIds) {
@@ -129,3 +177,11 @@ const char *translateCStr_Lang(const char *textWithIds) {
129 translate_Lang(text); 177 translate_Lang(text);
130 return cstr_String(text); 178 return cstr_String(text);
131} 179}
180
181const char *formatCStr_Lang(const char *formatMsgId, int count) {
182 return format_CStr(cstrCount_Lang(formatMsgId, count), count);
183}
184
185const char *formatCStrs_Lang(const char *formatMsgId, size_t count) {
186 return format_CStr(cstrCount_Lang(formatMsgId, (int) count), count);
187}