Fix gettext reload bugs (e.g. inability to disable gettext
once enabled). * grub-core/gettext/gettext.c: Encapsulate all static variables in main_context and secondary_context. All functions updated. (grub_gettext_translate): Rename to ... (grub_gettext_translate_real): ... this. Return NULL on failed translate. (grub_gettext_translate): Handle secondary context. (grub_gettext_delete_list): Close file and zero-out the context. (grub_mofile_open): Don't call grub_gettext_delete_list. Don't close file. (grub_gettext_init_ext): Call grub_gettext_init_ext. Skip loading if locale="" to avoid pointless error message. (grub_gettext_env_write_lang): Update lang even if load fails. Handle secondary context. (grub_gettext_reread_prefix): New function. (read_main): Likewise. (read_secondary): Likewise. (GRUB_MOD_INIT): Handle secondary context. Hook and export variables. (GRUB_MOD_FINI): Handle secondary context. Don't close file. * grub-core/normal/main.c (read_lists): Call grub_gettext_reread_prefix. * include/grub/normal.h (grub_gettext_reread_prefix): New proto.
This commit is contained in:
		
							parent
							
								
									8e56f87007
								
							
						
					
					
						commit
						17f38c0f8c
					
				
					 4 changed files with 176 additions and 74 deletions
				
			
		
							
								
								
									
										26
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								ChangeLog
									
										
									
									
									
								
							|  | @ -1,3 +1,29 @@ | ||||||
|  | 2012-03-10  Vladimir Serbinenko  <phcoder@gmail.com> | ||||||
|  | 
 | ||||||
|  | 	Fix gettext reload bugs (e.g. inability to disable gettext | ||||||
|  | 	once enabled). | ||||||
|  | 
 | ||||||
|  | 	* grub-core/gettext/gettext.c: Encapsulate all static variables in | ||||||
|  | 	main_context and secondary_context. All functions updated. | ||||||
|  | 	(grub_gettext_translate): Rename to ... | ||||||
|  | 	(grub_gettext_translate_real): ... this. Return NULL on failed | ||||||
|  | 	translate. | ||||||
|  | 	(grub_gettext_translate): Handle secondary context. | ||||||
|  | 	(grub_gettext_delete_list): Close file and zero-out the context. | ||||||
|  | 	(grub_mofile_open): Don't call grub_gettext_delete_list. | ||||||
|  | 	Don't close file. | ||||||
|  | 	(grub_gettext_init_ext): Call grub_gettext_init_ext. Skip loading | ||||||
|  | 	if locale="" to avoid pointless error message. | ||||||
|  | 	(grub_gettext_env_write_lang): Update lang even if load fails. | ||||||
|  | 	Handle secondary context. | ||||||
|  | 	(grub_gettext_reread_prefix): New function. | ||||||
|  | 	(read_main): Likewise. | ||||||
|  | 	(read_secondary): Likewise. | ||||||
|  | 	(GRUB_MOD_INIT): Handle secondary context. Hook and export variables. | ||||||
|  | 	(GRUB_MOD_FINI): Handle secondary context. Don't close file. | ||||||
|  | 	* grub-core/normal/main.c (read_lists): Call grub_gettext_reread_prefix. | ||||||
|  | 	* include/grub/normal.h (grub_gettext_reread_prefix): New proto. | ||||||
|  | 
 | ||||||
| 2012-03-10  Vladimir Serbinenko  <phcoder@gmail.com> | 2012-03-10  Vladimir Serbinenko  <phcoder@gmail.com> | ||||||
| 
 | 
 | ||||||
| 	* configure.ac: Decrease warning level to avoid spurious warnings and | 	* configure.ac: Decrease warning level to avoid spurious warnings and | ||||||
|  |  | ||||||
|  | @ -34,13 +34,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); | ||||||
|    http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
 |    http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
 | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| 
 | static struct grub_gettext_context main_context, secondary_context; | ||||||
| static grub_file_t fd_mo; |  | ||||||
| 
 |  | ||||||
| static grub_off_t grub_gettext_offset_original; |  | ||||||
| static grub_off_t grub_gettext_offset_translation; |  | ||||||
| static grub_size_t grub_gettext_max; |  | ||||||
| static int grub_gettext_max_log; |  | ||||||
| 
 | 
 | ||||||
| static const char *(*grub_gettext_original) (const char *s); | static const char *(*grub_gettext_original) (const char *s); | ||||||
| 
 | 
 | ||||||
|  | @ -50,8 +44,6 @@ struct grub_gettext_msg | ||||||
|   char *translated; |   char *translated; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct grub_gettext_msg *grub_gettext_msg_list = NULL; |  | ||||||
| 
 |  | ||||||
| struct header | struct header | ||||||
| { | { | ||||||
|   grub_uint32_t magic; |   grub_uint32_t magic; | ||||||
|  | @ -67,6 +59,16 @@ struct string_descriptor | ||||||
|   grub_uint32_t offset; |   grub_uint32_t offset; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct grub_gettext_context | ||||||
|  | { | ||||||
|  |   grub_file_t fd_mo; | ||||||
|  |   grub_off_t grub_gettext_offset_original; | ||||||
|  |   grub_off_t grub_gettext_offset_translation; | ||||||
|  |   grub_size_t grub_gettext_max; | ||||||
|  |   int grub_gettext_max_log; | ||||||
|  |   struct grub_gettext_msg *grub_gettext_msg_list; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| #define MO_MAGIC_NUMBER 		0x950412de | #define MO_MAGIC_NUMBER 		0x950412de | ||||||
| 
 | 
 | ||||||
| static grub_err_t | static grub_err_t | ||||||
|  | @ -85,7 +87,8 @@ grub_gettext_pread (grub_file_t file, void *buf, grub_size_t len, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static char * | static char * | ||||||
| grub_gettext_getstr_from_position (grub_off_t off, | grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, | ||||||
|  | 				   grub_off_t off, | ||||||
| 				   grub_size_t position) | 				   grub_size_t position) | ||||||
| { | { | ||||||
|   grub_off_t internal_position; |   grub_off_t internal_position; | ||||||
|  | @ -97,7 +100,7 @@ grub_gettext_getstr_from_position (grub_off_t off, | ||||||
| 
 | 
 | ||||||
|   internal_position = (off + position * sizeof (desc)); |   internal_position = (off + position * sizeof (desc)); | ||||||
| 
 | 
 | ||||||
|   err = grub_gettext_pread (fd_mo, (char *) &desc, |   err = grub_gettext_pread (ctx->fd_mo, (char *) &desc, | ||||||
| 			    sizeof (desc), internal_position); | 			    sizeof (desc), internal_position); | ||||||
|   if (err) |   if (err) | ||||||
|     return NULL; |     return NULL; | ||||||
|  | @ -108,7 +111,7 @@ grub_gettext_getstr_from_position (grub_off_t off, | ||||||
|   if (!translation) |   if (!translation) | ||||||
|     return NULL; |     return NULL; | ||||||
| 
 | 
 | ||||||
|   err = grub_gettext_pread (fd_mo, translation, length, offset); |   err = grub_gettext_pread (ctx->fd_mo, translation, length, offset); | ||||||
|   if (err) |   if (err) | ||||||
|     { |     { | ||||||
|       grub_free (translation); |       grub_free (translation); | ||||||
|  | @ -120,63 +123,68 @@ grub_gettext_getstr_from_position (grub_off_t off, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const char * | static const char * | ||||||
| grub_gettext_gettranslation_from_position (grub_size_t position) | grub_gettext_gettranslation_from_position (struct grub_gettext_context *ctx, | ||||||
|  | 					   grub_size_t position) | ||||||
| { | { | ||||||
|   if (!grub_gettext_msg_list[position].translated) |   if (!ctx->grub_gettext_msg_list[position].translated) | ||||||
|     grub_gettext_msg_list[position].translated |     ctx->grub_gettext_msg_list[position].translated | ||||||
|       = grub_gettext_getstr_from_position (grub_gettext_offset_translation, |       = grub_gettext_getstr_from_position (ctx, | ||||||
|  | 					   ctx->grub_gettext_offset_translation, | ||||||
| 					   position); | 					   position); | ||||||
|   return grub_gettext_msg_list[position].translated; |   return ctx->grub_gettext_msg_list[position].translated; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const char * | static const char * | ||||||
| grub_gettext_getstring_from_position (grub_size_t position) | grub_gettext_getstring_from_position (struct grub_gettext_context *ctx, | ||||||
|  | 				      grub_size_t position) | ||||||
| { | { | ||||||
|   if (!grub_gettext_msg_list[position].name) |   if (!ctx->grub_gettext_msg_list[position].name) | ||||||
|     grub_gettext_msg_list[position].name |     ctx->grub_gettext_msg_list[position].name | ||||||
|       = grub_gettext_getstr_from_position (grub_gettext_offset_original, |       = grub_gettext_getstr_from_position (ctx, | ||||||
|  | 					   ctx->grub_gettext_offset_original, | ||||||
| 					   position); | 					   position); | ||||||
|   return grub_gettext_msg_list[position].name; |   return ctx->grub_gettext_msg_list[position].name; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const char * | static const char * | ||||||
| grub_gettext_translate (const char *orig) | grub_gettext_translate_real (struct grub_gettext_context *ctx, | ||||||
|  | 			     const char *orig) | ||||||
| { | { | ||||||
|   grub_size_t current = 0; |   grub_size_t current = 0; | ||||||
|   int i; |   int i; | ||||||
|   const char *current_string; |   const char *current_string; | ||||||
|   static int depth = 0; |   static int depth = 0; | ||||||
| 
 | 
 | ||||||
|   if (!grub_gettext_msg_list || !fd_mo) |   if (!ctx->grub_gettext_msg_list || !ctx->fd_mo) | ||||||
|     return orig; |     return NULL; | ||||||
| 
 | 
 | ||||||
|   /* Shouldn't happen. Just a precaution if our own code
 |   /* Shouldn't happen. Just a precaution if our own code
 | ||||||
|      calls gettext somehow.  */ |      calls gettext somehow.  */ | ||||||
|   if (depth > 2) |   if (depth > 2) | ||||||
|     return orig; |     return NULL; | ||||||
|   depth++; |   depth++; | ||||||
| 
 | 
 | ||||||
|   /* Make sure we can use grub_gettext_translate for error messages.  Push
 |   /* Make sure we can use grub_gettext_translate for error messages.  Push
 | ||||||
|      active error message to error stack and reset error message.  */ |      active error message to error stack and reset error message.  */ | ||||||
|   grub_error_push (); |   grub_error_push (); | ||||||
| 
 | 
 | ||||||
|   for (i = grub_gettext_max_log; i >= 0; i--) |   for (i = ctx->grub_gettext_max_log; i >= 0; i--) | ||||||
|     { |     { | ||||||
|       grub_size_t test; |       grub_size_t test; | ||||||
|       int cmp; |       int cmp; | ||||||
| 
 | 
 | ||||||
|       test = current | (1 << i); |       test = current | (1 << i); | ||||||
|       if (test >= grub_gettext_max) |       if (test >= ctx->grub_gettext_max) | ||||||
| 	continue; | 	continue; | ||||||
| 
 | 
 | ||||||
|       current_string = grub_gettext_getstring_from_position (test); |       current_string = grub_gettext_getstring_from_position (ctx, test); | ||||||
| 
 | 
 | ||||||
|       if (!current_string) |       if (!current_string) | ||||||
| 	{ | 	{ | ||||||
| 	  grub_errno = GRUB_ERR_NONE; | 	  grub_errno = GRUB_ERR_NONE; | ||||||
| 	  grub_error_pop (); | 	  grub_error_pop (); | ||||||
| 	  depth--; | 	  depth--; | ||||||
| 	  return orig; | 	  return NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|       /* Search by bisection.  */ |       /* Search by bisection.  */ | ||||||
|  | @ -186,13 +194,13 @@ grub_gettext_translate (const char *orig) | ||||||
|       if (cmp == 0) |       if (cmp == 0) | ||||||
| 	{ | 	{ | ||||||
| 	  const char *ret = 0; | 	  const char *ret = 0; | ||||||
| 	  ret = grub_gettext_gettranslation_from_position (current); | 	  ret = grub_gettext_gettranslation_from_position (ctx, current); | ||||||
| 	  if (!ret) | 	  if (!ret) | ||||||
| 	    { | 	    { | ||||||
| 	      grub_errno = GRUB_ERR_NONE; | 	      grub_errno = GRUB_ERR_NONE; | ||||||
| 	      grub_error_pop (); | 	      grub_error_pop (); | ||||||
| 	      depth--; | 	      depth--; | ||||||
| 	      return orig; | 	      return NULL; | ||||||
| 	    } | 	    } | ||||||
| 	  grub_error_pop (); | 	  grub_error_pop (); | ||||||
| 	  depth--; | 	  depth--; | ||||||
|  | @ -202,27 +210,45 @@ grub_gettext_translate (const char *orig) | ||||||
| 
 | 
 | ||||||
|   grub_error_pop (); |   grub_error_pop (); | ||||||
|   depth--; |   depth--; | ||||||
|  |   return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char * | ||||||
|  | grub_gettext_translate (const char *orig) | ||||||
|  | { | ||||||
|  |   const char *ret; | ||||||
|  |   ret = grub_gettext_translate_real (&main_context, orig); | ||||||
|  |   if (ret) | ||||||
|  |     return ret; | ||||||
|  |   ret = grub_gettext_translate_real (&secondary_context, orig); | ||||||
|  |   if (ret) | ||||||
|  |     return ret; | ||||||
|   return orig; |   return orig; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| grub_gettext_delete_list (void) | grub_gettext_delete_list (struct grub_gettext_context *ctx) | ||||||
| { | { | ||||||
|   struct grub_gettext_msg *l = grub_gettext_msg_list; |   struct grub_gettext_msg *l = ctx->grub_gettext_msg_list; | ||||||
|   grub_size_t i; |   grub_size_t i; | ||||||
| 
 | 
 | ||||||
|   if (!l) |   if (!l) | ||||||
|     return; |     return; | ||||||
|   grub_gettext_msg_list = 0; |   ctx->grub_gettext_msg_list = 0; | ||||||
|   for (i = 0; i < grub_gettext_max; i++) |   for (i = 0; i < ctx->grub_gettext_max; i++) | ||||||
|     grub_free (l[i].name); |     grub_free (l[i].name); | ||||||
|   /* Don't delete the translated message because could be in use.  */ |   /* Don't delete the translated message because could be in use.  */ | ||||||
|   grub_free (l); |   grub_free (l); | ||||||
|  |   if (ctx->fd_mo) | ||||||
|  |     grub_file_close (ctx->fd_mo); | ||||||
|  |   ctx->fd_mo = 0; | ||||||
|  |   grub_memset (ctx, 0, sizeof (*ctx)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* This is similar to grub_file_open. */ | /* This is similar to grub_file_open. */ | ||||||
| static grub_err_t | static grub_err_t | ||||||
| grub_mofile_open (const char *filename) | grub_mofile_open (struct grub_gettext_context *ctx, | ||||||
|  | 		  const char *filename) | ||||||
| { | { | ||||||
|   struct header head; |   struct header head; | ||||||
|   grub_err_t err; |   grub_err_t err; | ||||||
|  | @ -257,25 +283,20 @@ grub_mofile_open (const char *filename) | ||||||
| 			 "mo: invalid mo version in file: %s", filename); | 			 "mo: invalid mo version in file: %s", filename); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|   grub_gettext_delete_list (); |   ctx->grub_gettext_offset_original = grub_le_to_cpu32 (head.offset_original); | ||||||
|  |   ctx->grub_gettext_offset_translation = grub_le_to_cpu32 (head.offset_translation); | ||||||
|  |   ctx->grub_gettext_max = grub_le_to_cpu32 (head.number_of_strings); | ||||||
|  |   for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log; | ||||||
|  |        ctx->grub_gettext_max_log++); | ||||||
| 
 | 
 | ||||||
|   grub_gettext_offset_original = grub_le_to_cpu32 (head.offset_original); |   ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max | ||||||
|   grub_gettext_offset_translation = grub_le_to_cpu32 (head.offset_translation); | 					    * sizeof (ctx->grub_gettext_msg_list[0])); | ||||||
|   grub_gettext_max = grub_le_to_cpu32 (head.number_of_strings); |   if (!ctx->grub_gettext_msg_list) | ||||||
|   for (grub_gettext_max_log = 0; grub_gettext_max >> grub_gettext_max_log; |  | ||||||
|        grub_gettext_max_log++); |  | ||||||
|   if (fd_mo) |  | ||||||
|     grub_file_close (fd_mo); |  | ||||||
|   fd_mo = 0; |  | ||||||
| 
 |  | ||||||
|   grub_gettext_msg_list = grub_zalloc (grub_gettext_max |  | ||||||
| 				       * sizeof (grub_gettext_msg_list[0])); |  | ||||||
|   if (!grub_gettext_msg_list) |  | ||||||
|     { |     { | ||||||
|       grub_file_close (fd); |       grub_file_close (fd); | ||||||
|       return grub_errno; |       return grub_errno; | ||||||
|     } |     } | ||||||
|   fd_mo = fd; |   ctx->fd_mo = fd; | ||||||
|   if (grub_gettext != grub_gettext_translate) |   if (grub_gettext != grub_gettext_translate) | ||||||
|     { |     { | ||||||
|       grub_gettext_original = grub_gettext; |       grub_gettext_original = grub_gettext; | ||||||
|  | @ -287,7 +308,8 @@ grub_mofile_open (const char *filename) | ||||||
| /* Returning grub_file_t would be more natural, but grub_mofile_open assigns
 | /* Returning grub_file_t would be more natural, but grub_mofile_open assigns
 | ||||||
|    to fd_mo anyway ...  */ |    to fd_mo anyway ...  */ | ||||||
| static grub_err_t | static grub_err_t | ||||||
| grub_mofile_open_lang (const char *part1, const char *part2, const char *locale) | grub_mofile_open_lang (struct grub_gettext_context *ctx, | ||||||
|  | 		       const char *part1, const char *part2, const char *locale) | ||||||
| { | { | ||||||
|   char *mo_file; |   char *mo_file; | ||||||
|   grub_err_t err; |   grub_err_t err; | ||||||
|  | @ -298,7 +320,7 @@ grub_mofile_open_lang (const char *part1, const char *part2, const char *locale) | ||||||
|   if (!mo_file) |   if (!mo_file) | ||||||
|     return grub_errno; |     return grub_errno; | ||||||
| 
 | 
 | ||||||
|   err = grub_mofile_open (mo_file); |   err = grub_mofile_open (ctx, mo_file); | ||||||
| 
 | 
 | ||||||
|   /* Will try adding .gz as well.  */ |   /* Will try adding .gz as well.  */ | ||||||
|   if (err) |   if (err) | ||||||
|  | @ -310,31 +332,36 @@ grub_mofile_open_lang (const char *part1, const char *part2, const char *locale) | ||||||
|       grub_free (mo_file_old); |       grub_free (mo_file_old); | ||||||
|       if (!mo_file) |       if (!mo_file) | ||||||
| 	return grub_errno; | 	return grub_errno; | ||||||
|       err = grub_mofile_open (mo_file); |       err = grub_mofile_open (ctx, mo_file); | ||||||
|     } |     } | ||||||
|   return err; |   return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static grub_err_t | static grub_err_t | ||||||
| grub_gettext_init_ext (const char *locale) | grub_gettext_init_ext (struct grub_gettext_context *ctx, | ||||||
|  | 		       const char *locale, | ||||||
|  | 		       const char *locale_dir, const char *prefix) | ||||||
| { | { | ||||||
|   const char *part1, *part2; |   const char *part1, *part2; | ||||||
|   grub_err_t err; |   grub_err_t err; | ||||||
| 
 | 
 | ||||||
|   if (!locale) |   grub_gettext_delete_list (ctx); | ||||||
|  | 
 | ||||||
|  |   if (!locale || locale[0] == 0) | ||||||
|     return 0; |     return 0; | ||||||
| 
 | 
 | ||||||
|   part1 = grub_env_get ("locale_dir"); |   part1 = locale_dir; | ||||||
|   part2 = ""; |   part2 = ""; | ||||||
|   if (!part1) |   if (!part1 || part1[0] == 0) | ||||||
|     { |     { | ||||||
|       part1 = grub_env_get ("prefix"); |       part1 = prefix; | ||||||
|       if (!part1) |  | ||||||
| 	return 0; |  | ||||||
|       part2 = "/locale"; |       part2 = "/locale"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|   err = grub_mofile_open_lang (part1, part2, locale); |   if (!part1 || part1[0] == 0) | ||||||
|  |     return 0; | ||||||
|  | 
 | ||||||
|  |   err = grub_mofile_open_lang (ctx, part1, part2, locale); | ||||||
| 
 | 
 | ||||||
|   /* ll_CC didn't work, so try ll.  */ |   /* ll_CC didn't work, so try ll.  */ | ||||||
|   if (err) |   if (err) | ||||||
|  | @ -346,7 +373,7 @@ grub_gettext_init_ext (const char *locale) | ||||||
| 	{ | 	{ | ||||||
| 	  *underscore = '\0'; | 	  *underscore = '\0'; | ||||||
| 	  grub_errno = GRUB_ERR_NONE; | 	  grub_errno = GRUB_ERR_NONE; | ||||||
| 	  err = grub_mofile_open_lang (part1, part2, lang); | 	  err = grub_mofile_open_lang (ctx, part1, part2, lang); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|       grub_free (lang); |       grub_free (lang); | ||||||
|  | @ -359,13 +386,52 @@ grub_gettext_env_write_lang (struct grub_env_var *var | ||||||
| 			     __attribute__ ((unused)), const char *val) | 			     __attribute__ ((unused)), const char *val) | ||||||
| { | { | ||||||
|   grub_err_t err; |   grub_err_t err; | ||||||
|   err = grub_gettext_init_ext (val); |   err = grub_gettext_init_ext (&main_context, val, grub_env_get ("locale_dir"), | ||||||
|  | 			       grub_env_get ("prefix")); | ||||||
|   if (err) |   if (err) | ||||||
|     { |  | ||||||
|     grub_print_error (); |     grub_print_error (); | ||||||
|       return NULL; | 
 | ||||||
|  |   err = grub_gettext_init_ext (&secondary_context, val, | ||||||
|  | 			       grub_env_get ("secondary_locale_dir"), 0); | ||||||
|  |   if (err) | ||||||
|  |     grub_print_error (); | ||||||
|  | 
 | ||||||
|  |   return grub_strdup (val); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | grub_gettext_reread_prefix (const char *val) | ||||||
|  | { | ||||||
|  |   grub_err_t err; | ||||||
|  |   err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"),  | ||||||
|  | 			       grub_env_get ("locale_dir"), | ||||||
|  | 			       val); | ||||||
|  |   if (err) | ||||||
|  |     grub_print_error (); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char * | ||||||
|  | read_main (struct grub_env_var *var | ||||||
|  | 	   __attribute__ ((unused)), const char *val) | ||||||
|  | { | ||||||
|  |   grub_err_t err; | ||||||
|  |   err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), val, | ||||||
|  | 			       grub_env_get ("prefix")); | ||||||
|  |   if (err) | ||||||
|  |     grub_print_error (); | ||||||
|  |   return grub_strdup (val); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char * | ||||||
|  | read_secondary (struct grub_env_var *var | ||||||
|  | 		__attribute__ ((unused)), const char *val) | ||||||
|  | { | ||||||
|  |   grub_err_t err; | ||||||
|  |   err = grub_gettext_init_ext (&secondary_context, grub_env_get ("lang"), val, | ||||||
|  | 			       0); | ||||||
|  |   if (err) | ||||||
|  |     grub_print_error (); | ||||||
|  | 
 | ||||||
|   return grub_strdup (val); |   return grub_strdup (val); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -388,7 +454,13 @@ GRUB_MOD_INIT (gettext) | ||||||
| 
 | 
 | ||||||
|   lang = grub_env_get ("lang"); |   lang = grub_env_get ("lang"); | ||||||
| 
 | 
 | ||||||
|   grub_gettext_init_ext (lang); |   grub_gettext_init_ext (&main_context, lang, grub_env_get ("locale_dir"), | ||||||
|  | 			 grub_env_get ("prefix")); | ||||||
|  |   grub_gettext_init_ext (&secondary_context, lang, | ||||||
|  | 			 grub_env_get ("secondary_locale_dir"), 0); | ||||||
|  | 
 | ||||||
|  |   grub_register_variable_hook ("locale_dir", NULL, read_main); | ||||||
|  |   grub_register_variable_hook ("secondary_locale_dir", NULL, read_secondary); | ||||||
| 
 | 
 | ||||||
|   grub_register_command_p1 ("gettext", grub_cmd_translate, |   grub_register_command_p1 ("gettext", grub_cmd_translate, | ||||||
| 			    N_("STRING"), | 			    N_("STRING"), | ||||||
|  | @ -403,14 +475,14 @@ GRUB_MOD_INIT (gettext) | ||||||
| 
 | 
 | ||||||
|   /* Preserve hooks after context changes.  */ |   /* Preserve hooks after context changes.  */ | ||||||
|   grub_env_export ("lang"); |   grub_env_export ("lang"); | ||||||
|  |   grub_env_export ("locale_dir"); | ||||||
|  |   grub_env_export ("secondary_locale_dir"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GRUB_MOD_FINI (gettext) | GRUB_MOD_FINI (gettext) | ||||||
| { | { | ||||||
|   if (fd_mo != 0) |   grub_gettext_delete_list (&main_context); | ||||||
|     grub_file_close (fd_mo); |   grub_gettext_delete_list (&secondary_context); | ||||||
| 
 |  | ||||||
|   grub_gettext_delete_list (); |  | ||||||
| 
 | 
 | ||||||
|   grub_gettext = grub_gettext_original; |   grub_gettext = grub_gettext_original; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -269,6 +269,7 @@ read_lists (const char *val) | ||||||
|       read_crypto_list (val); |       read_crypto_list (val); | ||||||
|       read_terminal_list (val); |       read_terminal_list (val); | ||||||
|     } |     } | ||||||
|  |   grub_gettext_reread_prefix (val); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static char * | static char * | ||||||
|  |  | ||||||
|  | @ -136,4 +136,7 @@ void grub_normal_auth_fini (void); | ||||||
| grub_command_t | grub_command_t | ||||||
| grub_dyncmd_get_cmd (grub_command_t cmd); | grub_dyncmd_get_cmd (grub_command_t cmd); | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | grub_gettext_reread_prefix (const char *val); | ||||||
|  | 
 | ||||||
| #endif /* ! GRUB_NORMAL_HEADER */ | #endif /* ! GRUB_NORMAL_HEADER */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue