static const char * grub_gettext_translate_real (struct grub_gettext_context *ctx, const char *orig) { grub_size_t current = 0; int i; const char *current_string; static int depth = 0; if (!ctx->grub_gettext_msg_list || !ctx->fd_mo) return NULL; /* Shouldn't happen. Just a precaution if our own code calls gettext somehow. */ if (depth > 2) return NULL; depth++; /* Make sure we can use grub_gettext_translate for error messages. Push active error message to error stack and reset error message. */ grub_error_push (); for (i = ctx->grub_gettext_max_log; i >= 0; i--) { grub_size_t test; int cmp; test = current | (1 << i); if (test >= ctx->grub_gettext_max) continue; current_string = grub_gettext_getstring_from_position (ctx, test); if (!current_string) { grub_errno = GRUB_ERR_NONE; grub_error_pop (); depth--; return NULL; } /* Search by bisection. */ cmp = grub_strcmp (current_string, orig); if (cmp <= 0) current = test; if (cmp == 0) { const char *ret = 0; ret = grub_gettext_gettranslation_from_position (ctx, current); if (!ret) { grub_errno = GRUB_ERR_NONE; grub_error_pop (); depth--; return NULL; } grub_error_pop (); depth--; return ret; } } if (current == 0 && ctx->grub_gettext_max != 0) { current_string = grub_gettext_getstring_from_position (ctx, 0); if (!current_string) { grub_errno = GRUB_ERR_NONE; grub_error_pop (); depth--; return NULL; } if (grub_strcmp (current_string, orig) == 0) { const char *ret = 0; ret = grub_gettext_gettranslation_from_position (ctx, current); if (!ret) { grub_errno = GRUB_ERR_NONE; grub_error_pop (); depth--; return NULL; } grub_error_pop (); depth--; return ret; } } grub_error_pop (); depth--; return NULL; }
static const char * grub_gettext_translate (const char *orig) { char *current_string; const char *ret; int min, max, current; int found = 0; struct grub_gettext_msg *cur; /* Make sure we can use grub_gettext_translate for error messages. Push active error message to error stack and reset error message. */ grub_error_push (); cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list), orig); if (cur) { grub_error_pop (); return cur->translated; } if (fd_mo == 0) { grub_error_pop (); return orig; } min = 0; max = grub_gettext_max; current = (max + min) / 2; while (current != min && current != max && found == 0) { current_string = grub_gettext_getstring_from_position (current); /* Search by bisection. */ if (grub_strcmp (current_string, orig) < 0) { grub_free (current_string); min = current; } else if (grub_strcmp (current_string, orig) > 0) { grub_free (current_string); max = current; } else if (grub_strcmp (current_string, orig) == 0) { grub_free (current_string); found = 1; } current = (max + min) / 2; } ret = found ? grub_gettext_gettranslation_from_position (current) : orig; if (found) { cur = grub_zalloc (sizeof (*cur)); if (cur) { cur->name = grub_strdup (orig); if (cur->name) { cur->translated = ret; grub_list_push (GRUB_AS_LIST_P (&grub_gettext_msg_list), GRUB_AS_LIST (cur)); } } else grub_errno = GRUB_ERR_NONE; } grub_error_pop (); return ret; }