Complete.Org: Mailing Lists: Archives: freeciv-i18n: January 2004:
[freeciv-i18n] Re: Ordinal number i18n patch
Home

[freeciv-i18n] Re: Ordinal number i18n patch

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: matusik_s@xxxxx
Cc: Freeciv i18n <freeciv-i18n@xxxxxxxxxxx>
Subject: [freeciv-i18n] Re: Ordinal number i18n patch
From: Mateusz Stefek <mstefek@xxxxxxxxx>
Date: Tue, 13 Jan 2004 09:18:31 +0100
Reply-to: matusik_s@xxxxx

> What do you think about attached patch?
> It shouldn't be very hard to create pattern for any language here.
> --
> mateusz
>=20
> -- Binary/unsupported file stripped by Ecartis --
> -- Type: text/x-diff
>=20
>=20
Ok I'll paste it here:
--- freeorig/server/report.c    2003-12-02 09:16:19.000000000 +0100
+++ freeciv/server/report.c     2004-01-12 23:33:19.000000000 +0100
@@ -576,26 +576,89 @@
 }
=20
 /**************************************************************************
-...
+ This function is sane only for 0 < num < 99
 **************************************************************************/
 static const char *number_to_ordinal_string(int num)
 {
+  /*=20
+     I18n-ing this stuff isn't easy
+     Few examples:
+     English: (num%10 =3D=3D 0 ||num%10 >4 || (num >=3D 11 && num <=3D 19)=
)? "st" :
+       (num%10 =3D=3D 1)? "st" :(num%10 =3D=3D 2) ? "nd" : "rd"
+     Polish: (num%10 =3D=3D 0 || num%10 =3D=3D 4 || num%10 =3D=3D 5 ||
+       num%10 =3D=3D 6 || num%10 =3D=3D 9 || (num >=3D 11 && num <=3D 19))=
? "ty" :
+       (num%10 =3D=3D 1)? "wszy" : (num%10=3D=3D2)? "gi":
+       (num%10=3D=3D3)? "ci" : "my"
+     Catalan: (num =3D=3D 1) ? "r" : (num =3D=3D 2)? "n" : (num=3D=3D3)? "=
r":
+       (num =3D=3D 4) ? "t" : "e"
+     French:  (num =3D=3D 1) ? "er" : "eme"
+     Russian:  (like Polish but with exeption at 40)
+   */
   static char buf[16];
-  char fmt[] =3D "(%d%s)";
-
-  assert(num > 0);
+  static char buf2[20];
+  char *pattern;
+  char *p;
+  bool I[2][10];
+  int state;
+  int i;
+ =20
+  assert(num > 0 && num < 100);
=20
-  if ((num % 10) =3D=3D 1 && num !=3D 11) {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("st"));
-  } else if ((num % 10) =3D=3D 2 && num !=3D 12) {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("nd"));
-  } else if ((num % 10) =3D=3D 3 && num !=3D 13) {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("rd"));
-  } else {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("th"));
+  pattern =3D=20
+    /* TRANS: This pattern is used to translate ordinal strings
+       like 1st or 2nd or 24th
+       It should be formatted like
+       [X1[Y1]]S1[X2[Y2]]S2...[Xm[Ym]]Sm|Def
+       Where Xi and Yi are list of digits and Si,Def are strings.
+       n matches [XXXX[YYYY]] if n/10 is in X _AND_ n%10 in Y
+       Program searches for first [Xi[Yi]] that given number matches=20
+       and returns Si. When nothing is found Def is returned.
+     */
+    Q_("?numeral:[023456789[1]]st[023456789[2]]nd[023456789[3]]rd|th");
+  for (i =3D 0; i < 10; i++) {
+    I[0][i] =3D I[1][i] =3D false;
+  }
+  for (state =3D -1, p =3D pattern; *p; p++) {
+    switch (*p) {
+    case '[':
+      state++;
+      break;
+    case ']':
+      state--;
+      if (state =3D=3D -1) {
+        if (I[0][num / 10] && I[1][num % 10]) {
+          goto found;
+        }
+        for (i =3D 0; i < 10; i++) {
+          I[0][i] =3D I[1][i] =3D false;
+        }
+      }
+      break;
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      I[state][(*p) - '0'] =3D true;
+      break;
+    case '|':
+      goto found;
+    }
   }
+  assert(0);
=20
-  return buf;
+  found:=20
+  for (i =3D 0, p++; p[i] !=3D '|' && p[i] !=3D '[' && p[i] !=3D '\0'; i++=
) {
+    buf[i] =3D p[i];
+  }
+  buf[i] =3D '\0';
+  my_snprintf(buf2, sizeof(buf2), "(%d%s)", num, buf);
+  return buf2;
 }
=20
 /**************************************************************************



[Prev in Thread] Current Thread [Next in Thread]