mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[localization] add proto locale processing
* Also add sample localization test file
This commit is contained in:
		
							parent
							
								
									011dd93b7a
								
							
						
					
					
						commit
						eb54fd9833
					
				
					 6 changed files with 214 additions and 71 deletions
				
			
		
							
								
								
									
										20
									
								
								src/.msvc/rufus.loc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/.msvc/rufus.loc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | ataak | ||||||
|  | l "en-US" | ||||||
|  |  v 2 8 | ||||||
|  | # This is a comment | ||||||
|  | t IDD_TEST "OHOH\"OLA\"LA\"BLA\"DI\"" | ||||||
|  | t 	ANY_MORE "国民生活センターの発表によ" | ||||||
|  |  # another comment  | ||||||
|  |  asasas   | ||||||
|  |   | ||||||
|  |  sdsadsdaasd 12  | ||||||
|  | m IDD_CONTROL -12 +4a5 | ||||||
|  | 	r IDD_CONTROL2 +5 +10   | ||||||
|  | t IDD_MORE_BLURB "Yoda dadada daaddadada"  	  | ||||||
|  | 	"THIS IS PART OF NEXT LINE" | ||||||
|  | 	 " could I have "     | ||||||
|  |  " ANY MORE LINESUS???"  | ||||||
|  | 	# Test comment | ||||||
|  | # end | ||||||
|  | f "MS Dialog" 23 | ||||||
|  |   | ||||||
|  | @ -169,6 +169,7 @@ | ||||||
|     <ClCompile Include="..\dos.c" /> |     <ClCompile Include="..\dos.c" /> | ||||||
|     <ClCompile Include="..\icon.c" /> |     <ClCompile Include="..\icon.c" /> | ||||||
|     <ClCompile Include="..\iso.c" /> |     <ClCompile Include="..\iso.c" /> | ||||||
|  |     <ClCompile Include="..\locale.c" /> | ||||||
|     <ClCompile Include="..\net.c" /> |     <ClCompile Include="..\net.c" /> | ||||||
|     <ClCompile Include="..\parser.c" /> |     <ClCompile Include="..\parser.c" /> | ||||||
|     <ClCompile Include="..\rufus.c" /> |     <ClCompile Include="..\rufus.c" /> | ||||||
|  | @ -185,6 +186,7 @@ | ||||||
|     <ClInclude Include="..\libcdio\cdio\iso9660.h" /> |     <ClInclude Include="..\libcdio\cdio\iso9660.h" /> | ||||||
|     <ClInclude Include="..\libcdio\cdio\logging.h" /> |     <ClInclude Include="..\libcdio\cdio\logging.h" /> | ||||||
|     <ClInclude Include="..\libcdio\cdio\udf.h" /> |     <ClInclude Include="..\libcdio\cdio\udf.h" /> | ||||||
|  |     <ClInclude Include="..\locale.h" /> | ||||||
|     <ClInclude Include="..\msapi_utf8.h" /> |     <ClInclude Include="..\msapi_utf8.h" /> | ||||||
|     <ClInclude Include="..\dos.h" /> |     <ClInclude Include="..\dos.h" /> | ||||||
|     <ClInclude Include="..\registry.h" /> |     <ClInclude Include="..\registry.h" /> | ||||||
|  |  | ||||||
|  | @ -60,6 +60,9 @@ | ||||||
|     <ClCompile Include="..\stdfn.c"> |     <ClCompile Include="..\stdfn.c"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\locale.c"> | ||||||
|  |       <Filter>Source Files</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\rufus.h"> |     <ClInclude Include="..\rufus.h"> | ||||||
|  | @ -101,6 +104,9 @@ | ||||||
|     <ClInclude Include="..\registry.h"> |     <ClInclude Include="..\registry.h"> | ||||||
|       <Filter>Header Files</Filter> |       <Filter>Header Files</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\locale.h"> | ||||||
|  |       <Filter>Header Files</Filter> | ||||||
|  |     </ClInclude> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="..\..\res\rufus.ico"> |     <None Include="..\..\res\rufus.ico"> | ||||||
|  |  | ||||||
							
								
								
									
										64
									
								
								src/locale.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/locale.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | ||||||
|  | /*
 | ||||||
|  |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  |  * Localization functions, a.k.a. "Everybody is doing it wrong but me!" | ||||||
|  |  * Copyright © 2013 Pete Batard <pete@akeo.ie> | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */ | ||||||
|  | #ifdef _CRTDBG_MAP_ALLOC | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <crtdbg.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <windows.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <wchar.h> | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | #include "rufus.h" | ||||||
|  | #include "msapi_utf8.h" | ||||||
|  | #include "locale.h" | ||||||
|  | 
 | ||||||
|  | /* s: quoted string, i: 32 bit signed integer, w single word (no space) */ | ||||||
|  | loc_parse parse_cmd[] = { | ||||||
|  | 	{ 'v', LC_VERSION, "ii" }, | ||||||
|  | 	{ 'l', LC_LOCALE, "s" }, | ||||||
|  | 	{ 'f', LC_FONT, "si" }, | ||||||
|  | 	{ 'p', LC_PARENT, "w" }, | ||||||
|  | 	{ 'd', LC_DIRECTION, "i" }, | ||||||
|  | 	{ 'r', LC_RESIZE, "wii" }, | ||||||
|  | 	{ 'm', LC_MOVE, "wii" }, | ||||||
|  | 	{ 't', LC_TEXT, "ws" } | ||||||
|  | }; | ||||||
|  | size_t PARSE_CMD_SIZE = ARRAYSIZE(parse_cmd); | ||||||
|  | 
 | ||||||
|  | void free_loc_cmd(loc_cmd* lcmd) | ||||||
|  | { | ||||||
|  | 	if (lcmd == NULL) | ||||||
|  | 		return; | ||||||
|  | 	safe_free(lcmd->text[0]); | ||||||
|  | 	safe_free(lcmd->text[1]); | ||||||
|  | 	free(lcmd); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOL execute_loc_cmd(loc_cmd* lcmd) | ||||||
|  | { | ||||||
|  | 	if (lcmd == NULL) | ||||||
|  | 		return FALSE; | ||||||
|  | 	uprintf("cmd #%d: ('%s', '%s') (%d, %d)\n", | ||||||
|  | 		lcmd->command, lcmd->text[0], lcmd->text[1], lcmd->num[0], lcmd->num[1]); | ||||||
|  | 	return TRUE; | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								src/locale.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/locale.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | ||||||
|  | /*
 | ||||||
|  |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  |  * Localization functions, a.k.a. "Everybody is doing it wrong but me!" | ||||||
|  |  * Copyright © 2013 Pete Batard <pete@akeo.ie> | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | // What we need for localization
 | ||||||
|  | // # Comment
 | ||||||
|  | // v 1 1                    // UI target version (major, minor)
 | ||||||
|  | // p IDD_DIALOG             // parent dialog for the following
 | ||||||
|  | // d 1                      // set text direction 0: left to right, 1 right to left
 | ||||||
|  | // f "MS Dialog" 12         // set font and font size
 | ||||||
|  | // r IDD_DIALOG +30 +30     // resize dialog (delta_w, delta_h)
 | ||||||
|  | // m IDC_START  -10 0       // move control (delta_x, delta_w)
 | ||||||
|  | // r IDC_START  0 +1        // resize control
 | ||||||
|  | // t IDC_START  "Demarrer"  // Change control text
 | ||||||
|  | // t IDC_LONG_CONTROL "Some text here"
 | ||||||
|  | //  "some continued text there"
 | ||||||
|  | // all parsed commands return: cmd, control_id, text, num1, num2
 | ||||||
|  | 
 | ||||||
|  | // TODO: display control name on mouseover
 | ||||||
|  | // Link to http://www.resedit.net/
 | ||||||
|  | 
 | ||||||
|  | enum loc_command_type { | ||||||
|  | 	LC_VERSION, | ||||||
|  | 	LC_LOCALE, | ||||||
|  | 	LC_FONT, | ||||||
|  | 	LC_PARENT, | ||||||
|  | 	LC_DIRECTION, | ||||||
|  | 	LC_RESIZE, | ||||||
|  | 	LC_MOVE, | ||||||
|  | 	LC_TEXT | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | typedef struct loc_cmd_struct { | ||||||
|  | 	int command; | ||||||
|  | 	char* text[2]; | ||||||
|  | 	int32_t num[2]; | ||||||
|  | } loc_cmd; | ||||||
|  | 
 | ||||||
|  | typedef struct loc_parse_struct { | ||||||
|  | 	char  c; | ||||||
|  | 	enum  loc_command_type cmd; | ||||||
|  | 	char* arg_type; | ||||||
|  | } loc_parse; | ||||||
|  | 
 | ||||||
|  | loc_parse parse_cmd[]; | ||||||
|  | size_t PARSE_CMD_SIZE; | ||||||
|  | 
 | ||||||
|  | void free_loc_cmd(loc_cmd* lcmd); | ||||||
|  | BOOL execute_loc_cmd(loc_cmd* lcmd); | ||||||
							
								
								
									
										127
									
								
								src/parser.c
									
										
									
									
									
								
							
							
						
						
									
										127
									
								
								src/parser.c
									
										
									
									
									
								
							|  | @ -33,56 +33,47 @@ | ||||||
| 
 | 
 | ||||||
| #include "rufus.h" | #include "rufus.h" | ||||||
| #include "msapi_utf8.h" | #include "msapi_utf8.h" | ||||||
| 
 | #include "locale.h" | ||||||
| 
 |  | ||||||
| // What we need for localization
 |  | ||||||
| // # Comment
 |  | ||||||
| // v 1 1                    // UI target version (major, minor)
 |  | ||||||
| // p IDD_DIALOG             // parent dialog for the following
 |  | ||||||
| // d 1                      // set text direction 0: left to right, 1 right to left
 |  | ||||||
| // f "MS Dialog" 12         // set font and font size
 |  | ||||||
| // r IDD_DIALOG +30 +30     // resize dialog (delta_w, delta_h)
 |  | ||||||
| // m IDC_START  -10 0       // move control (delta_x, delta_w)
 |  | ||||||
| // r IDC_START  0 +1        // resize control
 |  | ||||||
| // t IDC_START  "Demarrer"  // Change control text
 |  | ||||||
| // t IDC_LONG_CONTROL "Some text here"
 |  | ||||||
| //  "some continued text there"
 |  | ||||||
| // all parsed commands return: cmd, control_id, text, num1, num2
 |  | ||||||
| 
 |  | ||||||
| // TODO: display control name on mouseover
 |  | ||||||
| // Link to http://www.resedit.net/
 |  | ||||||
| 
 |  | ||||||
| typedef struct localization_command { |  | ||||||
| 	int command; |  | ||||||
| 	wchar_t* text1; |  | ||||||
| 	wchar_t* text2; |  | ||||||
| 	int32_t num1; |  | ||||||
| 	int32_t num2; |  | ||||||
| } loc_cmd; |  | ||||||
| 
 | 
 | ||||||
| int  loc_line_nr = 0; | int  loc_line_nr = 0; | ||||||
| char loc_filename[32]; | char loc_filename[32]; | ||||||
| #define luprintf(msg) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr); | #define luprintf(msg) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr); | ||||||
| 
 | 
 | ||||||
| // Parse localization command arguments and fill a localization command structure
 | // Fill a localization command buffer by parsing the line arguments
 | ||||||
| static void get_loc_data_args(char* arg_type, wchar_t* wline) { | // The command is allocated and must be freed by calling free_loc_cmd()
 | ||||||
|  | static loc_cmd* get_loc_cmd(wchar_t wc, wchar_t* wline) { | ||||||
| 	const wchar_t wspace[] = L" \t"; | 	const wchar_t wspace[] = L" \t"; | ||||||
| 	size_t i, r, arg_index; | 	size_t i, j, k, r, ti = 0, ii = 0; | ||||||
| 	char str[1024];	// Fot testing only
 |  | ||||||
| 	long n; |  | ||||||
| 	wchar_t *endptr, *expected_endptr; | 	wchar_t *endptr, *expected_endptr; | ||||||
|  | 	loc_cmd* lcmd = NULL; | ||||||
|  | 
 | ||||||
|  | 	for (j=0; j<PARSE_CMD_SIZE; j++) { | ||||||
|  | 		if (wc == (wchar_t)parse_cmd[j].c) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 	if (j >= PARSE_CMD_SIZE) { | ||||||
|  | 		luprintf("unknown command"); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcmd = (loc_cmd*)calloc(sizeof(loc_cmd), 1); | ||||||
|  | 	if (lcmd == NULL) { | ||||||
|  | 		luprintf("could not allocate command"); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	lcmd->command = parse_cmd[j].cmd; | ||||||
| 
 | 
 | ||||||
| 	i = 0; | 	i = 0; | ||||||
| 	for (arg_index=0; arg_type[arg_index] != 0; arg_index++) { | 	for (k = 0; parse_cmd[j].arg_type[k] != 0; k++) { | ||||||
| 		// Skip leading spaces
 | 		// Skip leading spaces
 | ||||||
| 		i += wcsspn(&wline[i], wspace); | 		i += wcsspn(&wline[i], wspace); | ||||||
| 		r = i; | 		r = i; | ||||||
| 		switch(arg_type[arg_index]) { | 		switch(parse_cmd[j].arg_type[k]) { | ||||||
| 		case 's':	// quoted string
 | 		case 's':	// quoted string
 | ||||||
| 			// search leading quote
 | 			// search leading quote
 | ||||||
| 			if (wline[i++] != L'"') { | 			if (wline[i++] != L'"') { | ||||||
| 				luprintf("missing leading quote"); | 				luprintf("no start quote"); | ||||||
| 				return; | 				goto err; | ||||||
| 			} | 			} | ||||||
| 			r = i; | 			r = i; | ||||||
| 			// locate ending quote
 | 			// locate ending quote
 | ||||||
|  | @ -94,82 +85,76 @@ static void get_loc_data_args(char* arg_type, wchar_t* wline) { | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if (wline[i] == 0) { | 			if (wline[i] == 0) { | ||||||
| 				luprintf("missing ending quote"); | 				luprintf("no end quote"); | ||||||
| 				return; | 				goto err; | ||||||
| 			} | 			} | ||||||
| 			wline[i++] = 0; | 			wline[i++] = 0; | ||||||
| 			wchar_to_utf8_no_alloc(&wline[r], str, sizeof(str)); | 			lcmd->text[ti++] = wchar_to_utf8(&wline[r]); | ||||||
| 			uprintf("Got string: '%s'\n", str); |  | ||||||
| 			break; | 			break; | ||||||
| 		case 'w':	// single word
 | 		case 'w':	// single word
 | ||||||
| 			while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1])) | 			while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1])) | ||||||
| 				i++; | 				i++; | ||||||
| 			if (wline[i] != 0) | 			if (wline[i] != 0) | ||||||
| 				wline[i++] = 0; | 				wline[i++] = 0; | ||||||
| 			wchar_to_utf8_no_alloc(&wline[r], str, sizeof(str)); | 			lcmd->text[ti++] = wchar_to_utf8(&wline[r]); | ||||||
| 			uprintf("Got word: %s\n", str); |  | ||||||
| 			break; | 			break; | ||||||
| 		case 'i':	// integer
 | 		case 'i':	// 32 bit signed integer
 | ||||||
| 			while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1])) | 			while ((wline[i] != 0) && (wline[i] != wspace[0]) && (wline[i] != wspace[1])) | ||||||
| 				i++; | 				i++; | ||||||
| 			expected_endptr = &wline[i]; | 			expected_endptr = &wline[i]; | ||||||
| 			if (wline[i] != 0) | 			if (wline[i] != 0) | ||||||
| 				wline[i++] = 0; | 				wline[i++] = 0; | ||||||
| 			n = wcstol(&wline[r], &endptr, 10); | 			lcmd->num[ii++] = (int32_t)wcstol(&wline[r], &endptr, 10); | ||||||
| 			if (endptr != expected_endptr) { | 			if (endptr != expected_endptr) { | ||||||
| 				luprintf("could not read integer data"); | 				luprintf("invalid integer"); | ||||||
| 				return; | 				goto err; | ||||||
| 			} else { |  | ||||||
| 				uprintf("Got integer: %d\n", n); |  | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			uprintf("localization: unhandled arg_type '%c'\n", arg_type[arg_index]); | 			uprintf("localization: unhandled arg_type '%c'\n", parse_cmd[j].arg_type[k]); | ||||||
| 			break; | 			goto err; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	return lcmd; | ||||||
|  | 
 | ||||||
|  | err: | ||||||
|  | 	free_loc_cmd(lcmd); | ||||||
|  | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| // Parse an UTF-16 localization command line
 | // Parse an UTF-16 localization command line
 | ||||||
| static void* get_loc_data_line(wchar_t* wline) | static void* get_loc_data_line(wchar_t* wline) | ||||||
| { | { | ||||||
| 	const wchar_t wspace[] = L" \t"; | 	const wchar_t wspace[] = L" \t"; | ||||||
| 	size_t i; | 	size_t i = 0; | ||||||
| 	wchar_t t; | 	wchar_t t; | ||||||
| 	BOOLEAN quoteth = FALSE; | 	loc_cmd* lcmd = NULL; | ||||||
| 	char line[8192]; | 	char* locale = "en-US"; | ||||||
|  | 	BOOL seek_locale = TRUE; | ||||||
| 
 | 
 | ||||||
| 	if ((wline == NULL) || (wline[0] == 0)) | 	if ((wline == NULL) || (wline[0] == 0)) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
| 	i = 0; |  | ||||||
| 
 |  | ||||||
| 	// Skip leading spaces
 | 	// Skip leading spaces
 | ||||||
| 	i += wcsspn(&wline[i], wspace); | 	i += wcsspn(&wline[i], wspace); | ||||||
| 
 | 
 | ||||||
| 	// Read token (NUL character will be read if EOL)
 | 	// Read token (NUL character will be read if EOL)
 | ||||||
| 	t = wline[i++]; | 	t = wline[i++]; | ||||||
| 	switch (t) { | 	if (t == L'#')	// Comment
 | ||||||
| 	case 't': |  | ||||||
| 		get_loc_data_args("ws", &wline[i]); |  | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	case 'f': | 	if ((t == 0) || ((wline[i] != wspace[0]) && (wline[i] != wspace[1]))) { | ||||||
| 		get_loc_data_args("si", &wline[i]); |  | ||||||
| 		return NULL; |  | ||||||
| 	case 'r': |  | ||||||
| 	case 'm': |  | ||||||
| 		get_loc_data_args("wii", &wline[i]); |  | ||||||
| 		return NULL; |  | ||||||
| 	case 'v': |  | ||||||
| 		get_loc_data_args("ii", &wline[i]); |  | ||||||
| 		return NULL; |  | ||||||
| 	case '#':	// comment
 |  | ||||||
| 		return NULL; |  | ||||||
| 	default: |  | ||||||
| 		wchar_to_utf8_no_alloc(wline, line, sizeof(line)); |  | ||||||
| 		luprintf("syntax error"); | 		luprintf("syntax error"); | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	lcmd = get_loc_cmd(t, &wline[i]); | ||||||
|  | 	// TODO: process LC_LOCALE in seek_locale mode
 | ||||||
|  | 	// TODO: check return value?
 | ||||||
|  | 	execute_loc_cmd(lcmd); | ||||||
|  | 	free_loc_cmd(lcmd); | ||||||
|  | 
 | ||||||
|  | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void *_reallocf(void *ptr, size_t size) | static __inline void *_reallocf(void *ptr, size_t size) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue