/* * dfltmsgstr * * choose an appropriate message by evaluating the plural expression, * and return it. */ static char * dfltmsgstr(Msg_g_node *gmnp, const char *msgstr, size_t msgstr_len, struct msg_pack *mp) { unsigned int pindex; size_t len; const char *p; #ifdef GETTEXT_DEBUG (void) printf("*************** dfltmsgstr(0x%p, \"%s\", %d, 0x%p)\n", (void *)gmnp, msgstr ? msgstr : "(null)", msgstr_len, (void *)mp); printgnumsg(gmnp, 0); printmp(mp, 0); #endif if (mp->plural) { if (gmnp->plural) { pindex = plural_eval(gmnp->plural, mp->n); } else { /* * This mo does not have plural information. * Using the English form. */ if (mp->n == 1) pindex = 0; else pindex = 1; } #ifdef GETTEXT_DEBUG (void) printf("plural_eval returned: %d\n", pindex); #endif if (pindex >= gmnp->nplurals) { /* should never happen */ pindex = 0; } p = msgstr; for (; pindex != 0; pindex--) { len = msgstr_len - (p - msgstr); p = memchr(p, '\0', len); if (!p) { /* * null byte not found * this should never happen */ char *result; DFLTMSG(result, mp->msgid1, mp->msgid2, mp->n, mp->plural); return (result); } p++; /* skip */ } return ((char *)p); } return ((char *)msgstr); }
/* Evaluates the plural formula for min <= n <= max and returns the estimated number of times the value j was assumed. */ static unsigned int plural_expression_histogram (const struct plural_distribution *self, int min, int max, unsigned long j) { if (min < 0) min = 0; /* Limit the number of evaluations. Nothing interesting happens beyond 1000. */ if (max - min > 1000) max = min + 1000; if (min <= max) { const struct expression *expr = self->expr; unsigned long n; unsigned int count; /* Protect against arithmetic exceptions. */ install_sigfpe_handler (); count = 0; for (n = min; n <= max; n++) { unsigned long val = plural_eval (expr, n); if (val == j) count++; } /* End of protection against arithmetic exceptions. */ uninstall_sigfpe_handler (); return count; } else return 0; }
char * _clic_ngettext(const char *msg, const char *nmsg, int n) { char *sp = 0; int l = 0; if (!lp && !inited) { inited = 1; lp = init_locale("clip"); } if (!lp) goto ret; #ifdef PO_COMPAT { int l1, l2; char *buf; l1 = strlen(msg); l2 = strlen(nmsg); #ifdef OS_MINGW buf = malloc(l1 + l2 + 2); #else buf = alloca(l1 + l2 + 2); #endif memcpy(buf, msg, l1); memcpy(buf + l1 + 1, nmsg, l2); buf[l1] = PO_COMPAT_CHAR; buf[l1 + l2 + 1] = 0; sp = find_msg(lp, buf, &l); #ifdef OS_MINGW free(buf); #endif } #endif if (!sp) sp = find_msg(lp, msg, &l); if (sp) { int i; unsigned long int nn; char *ep; if (!lp->pd) { if (n == 1) return tr_charset(lp, sp); sp = find_msg(lp, nmsg, &l); if (sp) return tr_charset(lp, sp); else return (char *) nmsg; } nn = plural_eval(lp->pd, n); ep = sp + l; for (i = 0; i < lp->nplural && sp < ep; i++) { char *p; #ifdef PO_COMPAT p = strchr(sp, PO_COMPAT_CHAR); if (!p) { l = strlen(sp); break; } else { l = p - sp; p++; } #else p = sp + strlen(sp) + 1; #endif if (p >= ep || i >= nn) break; sp = p; } #ifdef PO_COMPAT { /* this is a memleak!!! but... */ char *rp; rp = (char *) malloc(l + 1); memcpy(rp, sp, l); rp[l] = 0; return tr_charset(lp, rp); } #else return tr_charset(lp, sp); #endif } ret: return n > 1 ? (char *) nmsg : (char *) msg; }