| 
									
										
										
										
											2024-03-11 13:05:37 -05:00
										 |  |  | """Functions used to generate source files during build time""" | 
					
						
							| 
									
										
										
										
											2024-01-15 13:14:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-17 23:23:55 +01:00
										 |  |  | import os | 
					
						
							|  |  |  | import os.path | 
					
						
							| 
									
										
										
										
											2022-03-24 21:12:53 +02:00
										 |  |  | import subprocess | 
					
						
							|  |  |  | import tempfile | 
					
						
							|  |  |  | import uuid | 
					
						
							| 
									
										
										
										
											2024-05-21 15:14:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  | import methods | 
					
						
							| 
									
										
										
										
											2018-03-17 23:23:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-21 11:07:42 -05:00
										 |  |  | def doc_data_class_path_builder(target, source, env): | 
					
						
							|  |  |  |     paths = dict(sorted(source[0].read().items())) | 
					
						
							|  |  |  |     data = "\n".join([f'\t{{"{key}", "{value}"}},' for key, value in paths.items()]) | 
					
						
							|  |  |  |     with methods.generated_wrapper(str(target[0])) as file: | 
					
						
							|  |  |  |         file.write( | 
					
						
							|  |  |  |             f"""\
 | 
					
						
							|  |  |  | struct _DocDataClassPath {{ | 
					
						
							|  |  |  | 	const char *name; | 
					
						
							|  |  |  | 	const char *path; | 
					
						
							|  |  |  | }}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline constexpr int _doc_data_class_path_count = {len(paths)}; | 
					
						
							|  |  |  | inline constexpr _DocDataClassPath _doc_data_class_paths[{len(paths) + 1}] = {{ | 
					
						
							|  |  |  | 	{data} | 
					
						
							|  |  |  | 	{{nullptr, nullptr}}, | 
					
						
							|  |  |  | }}; | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def register_exporters_builder(target, source, env): | 
					
						
							|  |  |  |     platforms = source[0].read() | 
					
						
							|  |  |  |     exp_inc = "\n".join([f'#include "platform/{p}/export/export.h"' for p in platforms]) | 
					
						
							|  |  |  |     exp_reg = "\n\t".join([f"register_{p}_exporter();" for p in platforms]) | 
					
						
							|  |  |  |     exp_type = "\n\t".join([f"register_{p}_exporter_types();" for p in platforms]) | 
					
						
							|  |  |  |     with methods.generated_wrapper(str(target[0])) as file: | 
					
						
							|  |  |  |         file.write( | 
					
						
							|  |  |  |             f"""\
 | 
					
						
							|  |  |  | #include "register_exporters.h" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {exp_inc} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void register_exporters() {{ | 
					
						
							|  |  |  | 	{exp_reg} | 
					
						
							|  |  |  | }} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void register_exporter_types() {{ | 
					
						
							|  |  |  | 	{exp_type} | 
					
						
							|  |  |  | }} | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-17 23:23:55 +01:00
										 |  |  | def make_doc_header(target, source, env): | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |     buffer = b"".join([methods.get_buffer(src) for src in map(str, source)]) | 
					
						
							|  |  |  |     decomp_size = len(buffer) | 
					
						
							|  |  |  |     buffer = methods.compress_buffer(buffer) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with methods.generated_wrapper(str(target[0])) as file: | 
					
						
							|  |  |  |         file.write(f"""\
 | 
					
						
							|  |  |  | inline constexpr const char *_doc_data_hash = "{hash(buffer)}"; | 
					
						
							|  |  |  | inline constexpr int _doc_data_compressed_size = {len(buffer)}; | 
					
						
							|  |  |  | inline constexpr int _doc_data_uncompressed_size = {decomp_size}; | 
					
						
							|  |  |  | inline constexpr const unsigned char _doc_data_compressed[] = {{ | 
					
						
							|  |  |  | 	{methods.format_buffer(buffer, 1)} | 
					
						
							|  |  |  | }}; | 
					
						
							|  |  |  | """)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-17 23:10:51 +08:00
										 |  |  | def make_translations(target, source, env): | 
					
						
							|  |  |  |     target_h, target_cpp = str(target[0]), str(target[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     category = os.path.basename(target_h).split("_")[0] | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |     sorted_paths = sorted([src.abspath for src in source], key=lambda path: os.path.splitext(os.path.basename(path))[0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xl_names = [] | 
					
						
							|  |  |  |     msgfmt = env.Detect("msgfmt") | 
					
						
							|  |  |  |     if not msgfmt: | 
					
						
							|  |  |  |         methods.print_warning("msgfmt not found, using .po files instead of .mo") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-17 23:10:51 +08:00
										 |  |  |     with methods.generated_wrapper(target_cpp) as file: | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |         for path in sorted_paths: | 
					
						
							|  |  |  |             name = os.path.splitext(os.path.basename(path))[0] | 
					
						
							| 
									
										
										
										
											2024-03-06 16:10:23 -03:00
										 |  |  |             # msgfmt erases non-translated messages, so avoid using it if exporting the POT. | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |             if msgfmt and name != category: | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                 mo_path = os.path.join(tempfile.gettempdir(), uuid.uuid4().hex + ".mo") | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                 cmd = f"{msgfmt} {path} --no-hash -o {mo_path}" | 
					
						
							| 
									
										
										
										
											2022-03-24 21:12:53 +02:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                     subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE).communicate() | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                     buffer = methods.get_buffer(mo_path) | 
					
						
							| 
									
										
										
										
											2022-03-24 21:12:53 +02:00
										 |  |  |                 except OSError as e: | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                     methods.print_warning( | 
					
						
							| 
									
										
										
										
											2024-04-26 12:35:07 -05:00
										 |  |  |                         "msgfmt execution failed, using .po file instead of .mo: path=%r; [%s] %s" | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                         % (path, e.__class__.__name__, e) | 
					
						
							| 
									
										
										
										
											2022-03-24 21:12:53 +02:00
										 |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                     buffer = methods.get_buffer(path) | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                 finally: | 
					
						
							|  |  |  |                     try: | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                         if os.path.exists(mo_path): | 
					
						
							|  |  |  |                             os.remove(mo_path) | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                     except OSError as e: | 
					
						
							| 
									
										
										
										
											2024-03-06 16:10:23 -03:00
										 |  |  |                         # Do not fail the entire build if it cannot delete a temporary file. | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                         methods.print_warning( | 
					
						
							| 
									
										
										
										
											2024-04-26 12:35:07 -05:00
										 |  |  |                             "Could not delete temporary .mo file: path=%r; [%s] %s" % (mo_path, e.__class__.__name__, e) | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                         ) | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |                 buffer = methods.get_buffer(path) | 
					
						
							| 
									
										
										
										
											2024-03-06 16:10:23 -03:00
										 |  |  |                 if name == category: | 
					
						
							|  |  |  |                     name = "source" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |             decomp_size = len(buffer) | 
					
						
							|  |  |  |             buffer = methods.compress_buffer(buffer) | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |             file.write(f"""\
 | 
					
						
							|  |  |  | inline constexpr const unsigned char _{category}_translation_{name}_compressed[] = {{ | 
					
						
							|  |  |  | 	{methods.format_buffer(buffer, 1)} | 
					
						
							|  |  |  | }}; | 
					
						
							| 
									
										
										
										
											2018-03-17 23:23:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  | """)
 | 
					
						
							| 
									
										
										
										
											2018-03-17 23:23:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |             xl_names.append([name, len(buffer), decomp_size]) | 
					
						
							| 
									
										
										
										
											2020-03-18 18:34:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |         file.write(f"""\
 | 
					
						
							| 
									
										
										
										
											2025-09-17 23:10:51 +08:00
										 |  |  | #include "{target_h}" | 
					
						
							| 
									
										
										
										
											2020-03-18 18:34:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-17 23:10:51 +08:00
										 |  |  | const {category.capitalize()}TranslationList _{category}_translations[] = {{ | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  | """)
 | 
					
						
							| 
									
										
										
										
											2020-03-18 18:34:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |         for x in xl_names: | 
					
						
							|  |  |  |             file.write(f'\t{{ "{x[0]}", {x[1]}, {x[2]}, _{category}_translation_{x[0]}_compressed }},\n') | 
					
						
							| 
									
										
										
										
											2020-03-18 18:34:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  |         file.write("""\
 | 
					
						
							|  |  |  | 	{ nullptr, 0, 0, nullptr }, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2025-09-17 23:10:51 +08:00
										 |  |  | """)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with methods.generated_wrapper(target_h) as file: | 
					
						
							|  |  |  |         file.write(f"""\
 | 
					
						
							|  |  |  | struct {category.capitalize()}TranslationList {{ | 
					
						
							|  |  |  | 	const char* lang; | 
					
						
							|  |  |  | 	int comp_size; | 
					
						
							|  |  |  | 	int uncomp_size; | 
					
						
							|  |  |  | 	const unsigned char* data; | 
					
						
							|  |  |  | }}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern const {category.capitalize()}TranslationList _{category}_translations[]; | 
					
						
							| 
									
										
										
										
											2024-10-29 14:23:08 -05:00
										 |  |  | """)
 |