pax_global_header00006660000000000000000000000064152640437620014523gustar00rootroot0000000000000052 comment=8ff9380b1796aa141c07f335ac10a405f39f988f libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/000077500000000000000000000000001526404376200215505ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/LICENSES/000077500000000000000000000000001526404376200227555ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/LICENSES/LGPL-3.0-or-later.txt000066400000000000000000000164071526404376200263050ustar00rootroot00000000000000GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/NEWS000066400000000000000000000042241526404376200222510ustar00rootroot00000000000000libgedit-gfls news News in 0.5.0, 2026-10-15 ------------------------- - Translation updates. News in 0.5.alpha2, 2026-10-07 ------------------------------ - New class: GflsEncodingConverter. - New class: GflsUtf8AutoConverter (work-in-progress). - GflsValidatedString: make it a GObject class. - Change gfls_encoding_convert() API. - Remove GflsBytesRegion (no longer used). - Reference manual: * Write an introduction and a file loading overview. * Regroup related classes together in chapters. - Translation updates. News in 0.5.alpha, 2026-08-12 ----------------------------- - New features: GflsByteArray, GflsValidatedString, GflsValidatedStringBuilder, GflsValidatedStringChunk, UTF-8 validation, and some utils functions. - Encoding conversion: more docs and more tests. - GflsEncoding: class copied and adapted from libgedit-gtksourceview. - Don't annotate get_type() functions with G_GNUC_CONST. - Translation updates. News in 0.4.1, 2026-04-10 ------------------------- - Fix a unit test on big-endian architectures. - Translation updates. News in 0.4.0, 2026-03-27 ------------------------- - New features: GflsBytesRegion, GflsBytesRegionBuilder and GflsEncodingConvert. - New features imported from libgedit-gtksourceview: GflsIconv. - GflsInputStream: import improved version from libgedit-gtksourceview. - Translation updates. News in 0.3.1, 2025-11-17 ------------------------- - Translation updates. News in 0.3.0, 2025-03-08 ------------------------- - Improve some parts of the library (see the reference manual for changes). - Experiment with new Encoding interfaces and classes, but the code has been removed (a simpler approach is planned). - Improve the documentation. - Write more unit tests. - Translation updates. News in 0.2.1, 2024-12-07 ------------------------- - Translation updates. News in 0.2.0, 2024-08-31 ------------------------- - New classes and interfaces: GflsAttributeKeys, GflsLoaderConfig, GflsLoaderConfigSimple. - Build: add tests option. - Do some planning, write some notes. News in 0.1.0, 2024-04-27 (stable version) ------------------------------------------ - First version. - See the API reference for what's included. libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/README.md000066400000000000000000000006761526404376200230400ustar00rootroot00000000000000libgedit-gfls ============= Short description ----------------- Gedit Technology - File loading and saving Longer description ------------------ libgedit-gfls is part of [Gedit Technology](https://gedit-text-editor.org/technology.html). It is a module dedicated to file loading and saving for the needs of gedit and other similar text editors. Dependencies ------------ - GLib/GIO (required) - GTK 3 (optional, used for interactive tests) libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/build/000077500000000000000000000000001526404376200226475ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/build/.gitignore000066400000000000000000000000021526404376200246270ustar00rootroot00000000000000* libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/000077500000000000000000000000001526404376200225005ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/file-loading.md000066400000000000000000000014771526404376200253650ustar00rootroot00000000000000libgedit-gfls :: file loading TODO list ======================================= File loading steps ------------------ Name: GflsLoadingDriver, or GflsLoadingManager, or GflsLoader. Steps: 1. Create a GflsLoaderConfig(Simple). 2. (Optional) If GFile as input, query the GFileInfo. 3. (Optional) Check the GFileInfo against the GflsLoaderConfig(Simple) (check the file size). 4. Load all the raw content into memory (with max size). 5. (Optional) Transform if needed the raw content into the final content suitable to be inserted into a GtkTextBuffer (encoding conversion, splitting very long lines, escaping invalid characters and maybe others, keeping the relevant information along the way in order to reverse the operation - or show an error - upon saving). 6. Insert the final content into the GtkTextBuffer. libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/generic-and-extensible.md000066400000000000000000000013421526404376200273360ustar00rootroot00000000000000libgedit-gfls :: generic and extensible API =========================================== Have for Gfls a **generic** and **extensible** API for file loading and saving. Assumptions ----------- - Assume **GIO** use, in all cases. - Assume the intention to work with **text** (but allow workarounds if there are invalid chars). Use-case -------- Tepl has a framework (so with an inversion of control), with TeplAbstractFactory that apps subclass to customize the default behavior of Tepl. For a high-level file loading and saving API, Tepl can thus call the generic Gfls functions (i.e., probably just using interfaces, not concrete classes), and call TeplAbstractFactory functions to create and configure the concrete Gfls objects. libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/low-level-features.md000066400000000000000000000011311526404376200265400ustar00rootroot00000000000000libgedit-gfls :: low-level features =================================== Done ---- Loading: provide a maximum number of bytes to read, and get a GBytes as a result, knowing if it is truncated. Loading: detect if there is a very long line in a UTF-8 string. Split a GBytes into a list of chunks. Each chunk contains: - a GBytes - a boolean to tell if the GBytes is a valid UTF-8 string. To isolate invalid chars. Have a list of encodings. To implement ------------ Loading: encoding auto-detection. Loading: encoding conversion to UTF-8. Loading: detect BOM. Split very long lines (in UTF-8). libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/low-level-kit.md000066400000000000000000000015361526404376200255220ustar00rootroot00000000000000libgedit-gfls :: low-level kit ============================== There is some desire to create something: - Generic and extensible. - With a clear split between the backend and frontend. But where libgedit-gfls is located on the stack, it makes more sense to provide a low-level "kit" (above GIO and libICU, probably not GTK). That is, no interfaces, just concrete classes and functions (the "meat"). Providing useful utilities and building blocks. Solving specific and independent problems that anyway need to be solved ("divide and conquer"). Then in libgedit-tepl the building blocks can be assembled, creating a high-level API, something generic and extensible by the application, and so on. Integration ----------- To see the finish line, it is necessary to **integrate** the different features. Incrementally/progressively, not all at once at the end. libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/names.md000066400000000000000000000016211526404376200241250ustar00rootroot00000000000000libgedit-gfls :: names brainstorming ==================================== - GflsInfo, replacing GtkSourceFile or TeplFile. In the latter implementations, there is the ambiguity between a GFile (called a "location") and a TeplFile object (called "file"). With GflsInfo, a GFile object would remain to be called a "file", simply. And GflsInfo reflect the fact that it gathers a GFileInfo (basically) for later use. - GflsFile to extend GFile with more functions. - GflsLoader interface (that takes a GflsLoaderConfig as an input), with GflsLoaderBasic for dealing with UTF-8 only. - Driver: like a compiler driver that invokes several smaller programs. Have a driver for loading, and a driver for saving, that invoke smaller utilities with phases. The utilities are just classes and functions to be called (in the same process). A bit like a "Manager" class, except that the name is shorter. libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference/000077500000000000000000000000001526404376200244365ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference/libgedit-gfls-docs.xml000066400000000000000000000070141526404376200306240ustar00rootroot00000000000000 %gtkdocentities; ]> libgedit-gfls &package_api_version; Reference Manual For &package_string; At the current stage of development of libgedit-gfls, the API is experimental. There are no API stability guarantees. And there can be unfinished features. libgedit-gfls API Reference General Data Structures Character Encoding Conversion Misc Annexes Object Hierarchy Index of all symbols Index of new symbols in 0.1 Index of new symbols in 0.2 Index of new symbols in 0.3 Index of new symbols in 0.4 Index of new symbols in 0.5 libgedit-gfls-file-loading.xml000066400000000000000000000031041526404376200321430ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference %gtkdocentities; ]> libgedit-gfls File Loading Overview libgedit-gfls File Loading Overview Previous implementation With the previous implementation in gedit and libgedit-gtksourceview, loading big files was very slow. This was mainly because of many function calls to insert the content into the GtkTextBuffer in many small chunks. So that's something to avoid, ideally the whole content needs to be inserted at once into the GtkTextBuffer. Loading and inserting the content in small chunks was done to avoid having two copies in memory at a time. This goal was not worthwhile, because once the text is in the GtkTextBuffer, it consumes much more memory than the corresponding file size, especially with syntax highlighting enabled. There was a comment in the code with “welcome to a really big headache”. The code was messy and difficult to understand. With libgedit-gfls, things are hopefully better in that regard, by separating out many utilities. libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference/libgedit-gfls-intro.xml000066400000000000000000000032251526404376200310270ustar00rootroot00000000000000 %gtkdocentities; ]> libgedit-gfls Introduction libgedit-gfls Introduction libgedit-gfls is part of Gedit Technology. It is a library that extends GLib/GIO for text editors needs. Note that it only contains backend features, the frontend parts are implemented by other libgedit-* modules. As such, libgedit-gfls can be used for both GTK 3 and GTK 4 (for examples). “Gfls” initially was the acronym for “GLib-based File Loading and Saving”, since loading and saving documents in gedit involves a good chunk of code. But nowadays, libgedit-gfls should just be seen as a “libgedit-glib-extras” that extends GLib/GObject/GIO with more features useful for gedit and related apps. pkg-config name For libgedit-gfls &package_api_version;, the pkg-config name is: libgedit-gfls-&package_api_version; To compile a program that uses libgedit-gfls &package_api_version;, you can for example use the following command: $ gcc hello.c `pkg-config --cflags --libs libgedit-gfls-&package_api_version;` -o hello libgedit-gfls-sections.txt000066400000000000000000000134421526404376200314650ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/referencegfls/gfls.h
gfls-attribute-keys GflsAttributeKeys gfls_attribute_keys_new gfls_attribute_keys_add gfls_attribute_keys_to_string GFLS_ATTRIBUTE_KEYS GFLS_ATTRIBUTE_KEYS_CLASS GFLS_ATTRIBUTE_KEYS_GET_CLASS GFLS_IS_ATTRIBUTE_KEYS GFLS_IS_ATTRIBUTE_KEYS_CLASS GFLS_TYPE_ATTRIBUTE_KEYS GflsAttributeKeysClass GflsAttributeKeysPrivate gfls_attribute_keys_get_type
gfls-byte-array GflsByteArray gfls_byte_array_new gfls_byte_array_free_to_bytes gfls_byte_array_append gfls_byte_array_begin_write gfls_byte_array_end_write
gfls-encoding GflsEncoding GflsEncodingDuplicates gfls_encoding_new gfls_encoding_new_utf8 gfls_encoding_new_from_locale gfls_encoding_copy gfls_encoding_copy_func gfls_encoding_free gfls_encoding_get_charset gfls_encoding_has_known_charset gfls_encoding_get_name gfls_encoding_to_string gfls_encoding_is_utf8 gfls_encoding_is_locale gfls_encoding_equals gfls_encoding_compare_func gfls_encoding_get_all gfls_encoding_get_default_candidates gfls_encoding_remove_duplicates GFLS_TYPE_ENCODING GFLS_TYPE_ENCODING_DUPLICATES gfls_encoding_get_type gfls_encoding_duplicates_get_type
gfls-encoding-conversion gfls_encoding_convert gfls_encoding_try_convert
gfls-encoding-converter GflsEncodingConverter GflsEncodingConverterCallback gfls_encoding_converter_new gfls_encoding_converter_get_allow_invalid_bytes gfls_encoding_converter_set_allow_invalid_bytes gfls_encoding_converter_set_callback gfls_encoding_converter_open gfls_encoding_converter_feed gfls_encoding_converter_finish_feeding gfls_encoding_converter_get_lossy_conversion GFLS_ENCODING_CONVERTER GFLS_ENCODING_CONVERTER_CLASS GFLS_ENCODING_CONVERTER_GET_CLASS GFLS_IS_ENCODING_CONVERTER GFLS_IS_ENCODING_CONVERTER_CLASS GFLS_TYPE_ENCODING_CONVERTER GflsEncodingConverterClass GflsEncodingConverterPrivate gfls_encoding_converter_get_type
gfls-iconv GflsIconv GflsIconvResult gfls_iconv_new gfls_iconv_open gfls_iconv_feed gfls_iconv_feed_discard_output gfls_iconv_close gfls_iconv_free GFLS_TYPE_ICONV_RESULT gfls_iconv_result_get_type
gfls-init gfls_init gfls_finalize GFLS_H_INSIDE
gfls-input-stream GflsSimpleProgressCallback gfls_input_stream_read_async gfls_input_stream_read_finish
gfls-loader-basic GFLS_LOADER_ERROR GflsLoaderError gfls_loader_basic_load_async gfls_loader_basic_load_finish GFLS_TYPE_LOADER_ERROR gfls_loader_error_get_type gfls_loader_error_quark
gfls-loader-config GflsLoaderConfig GflsLoaderConfigInterface GFLS_IS_LOADER_CONFIG GFLS_LOADER_CONFIG GFLS_LOADER_CONFIG_GET_INTERFACE GFLS_TYPE_LOADER_CONFIG gfls_loader_config_get_type
gfls-loader-config-simple GflsLoaderConfigSimple gfls_loader_config_simple_new_from_file gfls_loader_config_simple_new_from_stream gfls_loader_config_simple_get_file gfls_loader_config_simple_get_stream GFLS_IS_LOADER_CONFIG_SIMPLE GFLS_IS_LOADER_CONFIG_SIMPLE_CLASS GFLS_LOADER_CONFIG_SIMPLE GFLS_LOADER_CONFIG_SIMPLE_CLASS GFLS_LOADER_CONFIG_SIMPLE_GET_CLASS GFLS_TYPE_LOADER_CONFIG_SIMPLE GflsLoaderConfigSimpleClass GflsLoaderConfigSimplePrivate gfls_loader_config_simple_get_type
gfls-unsaved-document-titles GflsUnsavedDocumentTitles GflsUnsavedDocumentTitleCallback gfls_unsaved_document_titles_new gfls_unsaved_document_titles_get_default gfls_unsaved_document_titles_allocate_number gfls_unsaved_document_titles_release_number gfls_unsaved_document_titles_get_title gfls_unsaved_document_titles_set_title_callback GFLS_IS_UNSAVED_DOCUMENT_TITLES GFLS_IS_UNSAVED_DOCUMENT_TITLES_CLASS GFLS_TYPE_UNSAVED_DOCUMENT_TITLES GFLS_UNSAVED_DOCUMENT_TITLES GFLS_UNSAVED_DOCUMENT_TITLES_CLASS GFLS_UNSAVED_DOCUMENT_TITLES_GET_CLASS GflsUnsavedDocumentTitlesClass GflsUnsavedDocumentTitlesPrivate gfls_unsaved_document_titles_get_type
gfls-utf8 gfls_utf8_find_very_long_line gfls_utf8_validate
gfls-utf8-auto-converter GflsUtf8AutoConverter gfls_utf8_auto_converter_new gfls_utf8_auto_converter_free gfls_utf8_auto_converter_get_validated_string gfls_utf8_auto_converter_get_chosen_encoding gfls_utf8_auto_converter_get_lossy_conversion
gfls-utils gfls_utils_bytes_to_hex_representation gfls_utils_find_nearest_power_of_two
gfls-validated-string GflsValidatedString gfls_validated_string_get_chunks GFLS_IS_VALIDATED_STRING GFLS_IS_VALIDATED_STRING_CLASS GFLS_TYPE_VALIDATED_STRING GFLS_VALIDATED_STRING GFLS_VALIDATED_STRING_CLASS GFLS_VALIDATED_STRING_GET_CLASS GflsValidatedStringClass GflsValidatedStringPrivate gfls_validated_string_get_type
gfls-validated-string-builder GflsValidatedStringBuilder gfls_validated_string_builder_new gfls_validated_string_builder_free_to_validated_string gfls_validated_string_builder_free gfls_validated_string_builder_append_chunk gfls_validated_string_builder_append_validated_string gfls_validated_string_builder_simplify
gfls-validated-string-chunk GflsValidatedStringChunk gfls_validated_string_chunk_new gfls_validated_string_chunk_ref gfls_validated_string_chunk_unref gfls_validated_string_chunk_get_bytes gfls_validated_string_chunk_get_valid gfls_validated_string_chunk_set_valid GFLS_TYPE_VALIDATED_STRING_CHUNK gfls_validated_string_chunk_get_type
libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference/meson.build000066400000000000000000000024001526404376200265740ustar00rootroot00000000000000subdir('xml') FS.copyfile( 'libgedit-gfls-sections.txt', 'libgedit-gfls-@0@-sections.txt'.format(GFLS_API_VERSION) ) gtkdoc_module_name = 'libgedit-gfls-@0@'.format(GFLS_API_VERSION) html_dir = get_option('prefix') / GNOME.gtkdoc_html_dir(gtkdoc_module_name) glib_docpath = dependency('glib-2.0').get_variable(pkgconfig: 'prefix') / 'share/gtk-doc/html/glib' gobject_docpath = dependency('gobject-2.0').get_variable(pkgconfig: 'prefix') / 'share/gtk-doc/html/gobject' gio_docpath = dependency('gio-2.0').get_variable(pkgconfig: 'prefix') / 'share/gtk-doc/html/gio' #gtk_docpath = dependency('gtk+-3.0').get_variable(pkgconfig: 'prefix') / 'share/gtk-doc/html/gtk3' GNOME.gtkdoc( gtkdoc_module_name, main_xml: 'libgedit-gfls-docs.xml', src_dir: include_directories('../../gfls/'), dependencies: GFLS_LIB_DEP, scan_args: ['--rebuild-types'], gobject_typesfile: 'libgedit-gfls-@0@.types'.format(GFLS_API_VERSION), fixxref_args: [ '--html-dir=@0@'.format(html_dir), '--extra-dir=@0@'.format(glib_docpath), '--extra-dir=@0@'.format(gobject_docpath), '--extra-dir=@0@'.format(gio_docpath), ], ignore_headers: [GFLS_PRIVATE_HEADERS], content_files: [ 'libgedit-gfls-file-loading.xml', 'libgedit-gfls-intro.xml', ], install: true ) libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference/xml/000077500000000000000000000000001526404376200252365ustar00rootroot00000000000000gtkdocentities.ent.in000066400000000000000000000001421526404376200313110ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference/xml libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/docs/reference/xml/meson.build000066400000000000000000000006401526404376200274000ustar00rootroot00000000000000gtkdocentities_conf_data = configuration_data() gtkdocentities_conf_data.set('PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), meson.project_version())) gtkdocentities_conf_data.set('PACKAGE_API_VERSION', GFLS_API_VERSION) gtkdocentities_filename = 'gtkdocentities.ent' configure_file( input: gtkdocentities_filename + '.in', output: gtkdocentities_filename, configuration: gtkdocentities_conf_data ) libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/000077500000000000000000000000001526404376200225035ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-attribute-keys.c000066400000000000000000000066311526404376200265620ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-attribute-keys.h" /** * SECTION:gfls-attribute-keys * @Title: GflsAttributeKeys * @Short_description: A list of #GFile attribute keys * * #GflsAttributeKeys is a small utility to build a list of #GFile attribute * keys. The result is a single string to pass as an argument to a function like * g_file_query_info(). * * It is useful for doing only a single query with a list of keys coming from * different parts of the program. To take an example, libgedit-gfls might have * its own list of keys to query, but it is desirable to ask the application for * additional keys. */ /* Rationale * ========= * * The goal is to get desired #GFileInfo attributes in one query. * * Reasons to do it in one query: * 1. To avoid unnecessary round-trips (?) (especially for remote files). * Actually I don't know how it is implemented in GIO and GVfs. In case of * doubt a single query is better since the implementation has the * *possibility* to optimize network usage. * 2. For convenience in the implementation, to just call one pair of * async()/finish() functions for that task. */ struct _GflsAttributeKeysPrivate { /* Element-type: "owned gchar *" */ GPtrArray *array; }; G_DEFINE_TYPE_WITH_PRIVATE (GflsAttributeKeys, gfls_attribute_keys, G_TYPE_OBJECT) static void gfls_attribute_keys_finalize (GObject *object) { GflsAttributeKeys *keys = GFLS_ATTRIBUTE_KEYS (object); g_clear_pointer (&keys->priv->array, g_ptr_array_unref); G_OBJECT_CLASS (gfls_attribute_keys_parent_class)->finalize (object); } static void gfls_attribute_keys_class_init (GflsAttributeKeysClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gfls_attribute_keys_finalize; } static void gfls_attribute_keys_init (GflsAttributeKeys *keys) { keys->priv = gfls_attribute_keys_get_instance_private (keys); keys->priv->array = g_ptr_array_new_null_terminated (0, g_free, TRUE); } /** * gfls_attribute_keys_new: * * Returns: (transfer full): a new #GflsAttributeKeys object. * Since: 0.2 */ GflsAttributeKeys * gfls_attribute_keys_new (void) { return g_object_new (GFLS_TYPE_ATTRIBUTE_KEYS, NULL); } /** * gfls_attribute_keys_add: * @keys: a #GflsAttributeKeys. * @str: the value to add. * * Adds @str to @keys. * * @str has the same semantics as the corresponding parameter of * g_file_query_info(). * * Since: 0.2 */ void gfls_attribute_keys_add (GflsAttributeKeys *keys, const gchar *str) { g_return_if_fail (GFLS_IS_ATTRIBUTE_KEYS (keys)); g_return_if_fail (str != NULL); g_ptr_array_add (keys->priv->array, g_strdup (str)); } /** * gfls_attribute_keys_to_string: * @keys: a #GflsAttributeKeys. * * Returns: (transfer full) (nullable): the complete string to pass to * g_file_query_info() (for example), or %NULL if the list is empty. * Since: 0.2 */ gchar * gfls_attribute_keys_to_string (GflsAttributeKeys *keys) { g_return_val_if_fail (GFLS_IS_ATTRIBUTE_KEYS (keys), NULL); if (keys->priv->array->len == 0) { return NULL; } /* The list is *not* optimized here (to remove duplicates, simplify when * there are wildcards, etc). It is already optimized in GIO, but as an * implementation detail: by g_file_attribute_matcher_new(), which is * called by g_file_query_info(). */ return g_strjoinv (",", (gchar **) keys->priv->array->pdata); } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-attribute-keys.h000066400000000000000000000033541526404376200265660ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_ATTRIBUTE_KEYS_H #define GFLS_ATTRIBUTE_KEYS_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS #define GFLS_TYPE_ATTRIBUTE_KEYS (gfls_attribute_keys_get_type ()) #define GFLS_ATTRIBUTE_KEYS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GFLS_TYPE_ATTRIBUTE_KEYS, GflsAttributeKeys)) #define GFLS_ATTRIBUTE_KEYS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GFLS_TYPE_ATTRIBUTE_KEYS, GflsAttributeKeysClass)) #define GFLS_IS_ATTRIBUTE_KEYS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GFLS_TYPE_ATTRIBUTE_KEYS)) #define GFLS_IS_ATTRIBUTE_KEYS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GFLS_TYPE_ATTRIBUTE_KEYS)) #define GFLS_ATTRIBUTE_KEYS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GFLS_TYPE_ATTRIBUTE_KEYS, GflsAttributeKeysClass)) typedef struct _GflsAttributeKeys GflsAttributeKeys; typedef struct _GflsAttributeKeysClass GflsAttributeKeysClass; typedef struct _GflsAttributeKeysPrivate GflsAttributeKeysPrivate; struct _GflsAttributeKeys { GObject parent; GflsAttributeKeysPrivate *priv; }; struct _GflsAttributeKeysClass { GObjectClass parent_class; gpointer padding[12]; }; G_MODULE_EXPORT GType gfls_attribute_keys_get_type (void); G_MODULE_EXPORT GflsAttributeKeys * gfls_attribute_keys_new (void); G_MODULE_EXPORT void gfls_attribute_keys_add (GflsAttributeKeys *keys, const gchar *str); G_MODULE_EXPORT gchar * gfls_attribute_keys_to_string (GflsAttributeKeys *keys); G_END_DECLS #endif /* GFLS_ATTRIBUTE_KEYS_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-byte-array.c000066400000000000000000000147601526404376200256670ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-byte-array.h" #include "gfls-utils.h" /** * SECTION:gfls-byte-array * @Title: GflsByteArray * @Short_description: Builds an array of bytes * * Builds an array of bytes. * * #GflsByteArray is similar to #GByteArray and #GString but with a smaller and * different API, and ensures that at the end of the operation, the resulting * #GBytes doesn't consume more memory than necessary by doing a reallocation at * the final size. */ struct _GflsByteArray { /* Can be NULL. */ guint8 *data; /* Does _not_ include the terminating nul byte. */ gsize n_bytes_written; /* Class invariant: * if (data != NULL) * n_bytes_written + 1 <= n_bytes_allocated */ gsize n_bytes_allocated; /* For the begin/end write operation. */ gsize n_bytes_reserved_for_write_operation; }; /* To consume less memory. */ static void realloc_at_perfect_fit (GflsByteArray *byte_array) { gsize exact_num_bytes_needed; exact_num_bytes_needed = byte_array->n_bytes_written + 1; if (exact_num_bytes_needed != byte_array->n_bytes_allocated) { byte_array->data = g_realloc (byte_array->data, exact_num_bytes_needed); byte_array->n_bytes_allocated = exact_num_bytes_needed; } } static gboolean write_operation_is_running (GflsByteArray *byte_array) { return byte_array->n_bytes_reserved_for_write_operation != 0; } /** * gfls_byte_array_new: (skip) * * Returns: (transfer full): a new and empty #GflsByteArray. Free with * gfls_byte_array_free_to_bytes(). * Since: 0.5 */ GflsByteArray * gfls_byte_array_new (void) { return g_new0 (GflsByteArray, 1); } /** * gfls_byte_array_free_to_bytes: * @byte_array: a #GflsByteArray. * * Transfers the data from @byte_array into a new immutable #GBytes, and frees * @byte_array. * * If no bytes have been added to @byte_array, %NULL is returned. * * A nul byte is added at the end, but should not be seen as part of the “real” * data. In other words, the data contained in the resulting #GBytes is always * nul-terminated, but this is not included in the #GBytes length. * * Note that embedded nul bytes can also be present inside the “real” data. * * This function ensures that the resulting #GBytes doesn't consume more memory * than necessary. * * Returns: (transfer full) (nullable): a #GBytes, or %NULL. * Since: 0.5 */ GBytes * gfls_byte_array_free_to_bytes (GflsByteArray *byte_array) { GBytes *bytes; g_return_val_if_fail (byte_array != NULL, NULL); if (byte_array->data == NULL) { return NULL; } /* Nul-terminate. */ byte_array->data[byte_array->n_bytes_written] = '\0'; realloc_at_perfect_fit (byte_array); bytes = g_bytes_new_take (byte_array->data, byte_array->n_bytes_written); g_free (byte_array); return bytes; } /** * gfls_byte_array_begin_write: * @byte_array: a #GflsByteArray. * @n_bytes_to_reserve: the maximum number of bytes that this write operation * will support. * * Begins a new write operation, to add bytes to the end of @byte_array. * * When a successful write operation is finished, call * gfls_byte_array_end_write(). If this function returns %NULL, don't call * gfls_byte_array_end_write(). * * Only one write operation at a time is supported. * * Be careful and avoid out-of-bounds writes! For a simpler method that copies * the bytes, see gfls_byte_array_append(). * * Returns: (nullable): the buffer position where to begin to write the new * bytes, or %NULL on failure. * Since: 0.5 */ guint8 * gfls_byte_array_begin_write (GflsByteArray *byte_array, gsize n_bytes_to_reserve) { gsize n_bytes_required = 0; g_return_val_if_fail (byte_array != NULL, NULL); g_return_val_if_fail (n_bytes_to_reserve != 0, NULL); g_return_val_if_fail (!write_operation_is_running (byte_array), NULL); if (!g_size_checked_add (&n_bytes_required, byte_array->n_bytes_written, n_bytes_to_reserve)) { return NULL; } /* +1 for the terminating nul. */ if (!g_size_checked_add (&n_bytes_required, n_bytes_required, 1)) { return NULL; } if (n_bytes_required > byte_array->n_bytes_allocated) { gsize n_bytes_to_allocate; /* It's probably better to allocate at a size equal to a power * of two. At least, that's how GString and GByteArray are * currently implemented. */ n_bytes_to_allocate = gfls_utils_find_nearest_power_of_two (n_bytes_required); if (n_bytes_to_allocate == 0) { n_bytes_to_allocate = n_bytes_required; } byte_array->data = g_realloc (byte_array->data, n_bytes_to_allocate); byte_array->n_bytes_allocated = n_bytes_to_allocate; } byte_array->n_bytes_reserved_for_write_operation = n_bytes_to_reserve; return byte_array->data + byte_array->n_bytes_written; } /** * gfls_byte_array_end_write: * @byte_array: a #GflsByteArray. * @n_bytes_written: the number of bytes added during this write operation. * * Ends a successful write operation that was started with * gfls_byte_array_begin_write(). * * @n_bytes_written must be less than or equal to @n_bytes_to_reserve that was * provided at the beginning of this write operation. * * After calling this function, you can call again gfls_byte_array_begin_write() * if you need to write more data to the @byte_array. * * Since: 0.5 */ void gfls_byte_array_end_write (GflsByteArray *byte_array, gsize n_bytes_written) { g_return_if_fail (byte_array != NULL); g_return_if_fail (write_operation_is_running (byte_array)); g_return_if_fail (n_bytes_written <= byte_array->n_bytes_reserved_for_write_operation); byte_array->n_bytes_written += n_bytes_written; byte_array->n_bytes_reserved_for_write_operation = 0; } /** * gfls_byte_array_append: * @byte_array: a #GflsByteArray. * @data: (nullable): the byte data to be added. * @size: the number of bytes to add. * * Adds the given bytes to the end of @byte_array, by doing a copy. * * If @data is %NULL or if @size is 0, it will return immediately. * * A write operation - as started with gfls_byte_array_begin_write() - must not * be ongoing. * * Since: 0.5 */ void gfls_byte_array_append (GflsByteArray *byte_array, const guint8 *data, gsize size) { guint8 *buffer_pos; g_return_if_fail (byte_array != NULL); g_return_if_fail (!write_operation_is_running (byte_array)); if (data == NULL || size == 0) { return; } buffer_pos = gfls_byte_array_begin_write (byte_array, size); if (buffer_pos == NULL) { return; } memcpy (buffer_pos, data, size); gfls_byte_array_end_write (byte_array, size); } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-byte-array.h000066400000000000000000000015401526404376200256640ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS typedef struct _GflsByteArray GflsByteArray; G_MODULE_EXPORT GflsByteArray * gfls_byte_array_new (void); G_MODULE_EXPORT GBytes * gfls_byte_array_free_to_bytes (GflsByteArray *byte_array); G_MODULE_EXPORT void gfls_byte_array_append (GflsByteArray *byte_array, const guint8 *data, gsize size); G_MODULE_EXPORT guint8 * gfls_byte_array_begin_write (GflsByteArray *byte_array, gsize n_bytes_to_reserve); G_MODULE_EXPORT void gfls_byte_array_end_write (GflsByteArray *byte_array, gsize n_bytes_written); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-encoding-conversion.c000066400000000000000000000137361526404376200275630ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2025-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-encoding-conversion.h" #include "gfls-encoding-converter.h" #include "gfls-iconv.h" #include "gfls-utils.h" #include "gfls-validated-string-builder.h" /** * SECTION:gfls-encoding-conversion * @Title: GflsEncodingConversion * @Short_description: High-level character encoding conversion * * High-level character encoding conversion functions. * * If you need more flexibility, there are lower-level utilities: * - #GflsEncodingConverter * - #GflsIconv */ static GBytes * escape_invalid_bytes (GBytes *input_bytes) { const guint8 *input_data; gsize input_size = 0; gchar *output_str; input_data = g_bytes_get_data (input_bytes, &input_size); output_str = gfls_utils_bytes_to_hex_representation (input_data, input_size); return g_bytes_new_take (output_str, strlen (output_str)); } static void converter_cb (GBytes *bytes, gboolean is_valid, gpointer user_data) { GflsValidatedStringBuilder *builder = user_data; GflsValidatedStringChunk *chunk = NULL; if (is_valid) { chunk = gfls_validated_string_chunk_new (bytes); gfls_validated_string_chunk_set_valid (chunk, TRUE); } else { GBytes *escaped_bytes; escaped_bytes = escape_invalid_bytes (bytes); chunk = gfls_validated_string_chunk_new (escaped_bytes); g_bytes_unref (escaped_bytes); gfls_validated_string_chunk_set_valid (chunk, FALSE); } gfls_validated_string_builder_append_chunk (builder, chunk); gfls_validated_string_chunk_unref (chunk); } /** * gfls_encoding_convert: (skip) * @input_bytes: the input #GBytes. * @from_encoding: source encoding. * @to_encoding: destination encoding. * @allow_invalid_bytes: whether to allow invalid bytes during the conversion. * @lossy_conversion: (out) (optional): whether * %GFLS_ICONV_RESULT_LOSSY_CONVERSION was encountered. * @error: location to a #GError, or %NULL to ignore errors. * * High-level function to convert a single #GBytes. * * Returns: (transfer full) (nullable): the #GflsValidatedString, or %NULL on * error. * Since: 0.5 */ GflsValidatedString * gfls_encoding_convert (GBytes *input_bytes, const GflsEncoding *from_encoding, const GflsEncoding *to_encoding, gboolean allow_invalid_bytes, gboolean *lossy_conversion, GError **error) { GflsEncodingConverter *converter; GflsValidatedStringBuilder *builder; if (lossy_conversion != NULL) { *lossy_conversion = FALSE; } g_return_val_if_fail (input_bytes != NULL, NULL); g_return_val_if_fail (from_encoding != NULL, NULL); g_return_val_if_fail (to_encoding != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, allow_invalid_bytes); builder = gfls_validated_string_builder_new (); gfls_encoding_converter_set_callback (converter, converter_cb, builder); if (!gfls_encoding_converter_open (converter, gfls_encoding_get_charset (from_encoding), gfls_encoding_get_charset (to_encoding), error)) { g_object_unref (converter); gfls_validated_string_builder_free (builder); return NULL; } if (!gfls_encoding_converter_feed (converter, g_bytes_get_data (input_bytes, NULL), g_bytes_get_size (input_bytes), error)) { g_object_unref (converter); gfls_validated_string_builder_free (builder); return NULL; } if (!gfls_encoding_converter_finish_feeding (converter, error)) { g_object_unref (converter); gfls_validated_string_builder_free (builder); return NULL; } if (lossy_conversion != NULL) { *lossy_conversion = gfls_encoding_converter_get_lossy_conversion (converter); } g_object_unref (converter); gfls_validated_string_builder_simplify (builder); return gfls_validated_string_builder_free_to_validated_string (builder); } /** * gfls_encoding_try_convert: * @input_bytes: a #GBytes. * @to_codeset: destination codeset. * @from_codeset: source codeset. * * Tries a conversion on @input_bytes, discarding the output. * * @from_codeset and @to_codeset must be compatible with iconv, see * gfls_iconv_open(). * * If @input_bytes ends with an incomplete multi-byte character, that part is * ignored. So @input_bytes can be for example the first chunk of a file when * loading it. * * Returns: %TRUE if and only if @input_bytes can be converted without errors, * without invalid characters and without fallback characters. * Since: 0.4 */ gboolean gfls_encoding_try_convert (GBytes *input_bytes, const gchar *to_codeset, const gchar *from_codeset) { GflsIconv *conv; const gchar *input_buffer; gsize input_buffer_size = 0; gchar *input_buffer_pos; gsize input_buffer_n_bytes_left; GflsIconvResult conv_result; gboolean success = FALSE; g_return_val_if_fail (input_bytes != NULL, FALSE); g_return_val_if_fail (to_codeset != NULL, FALSE); g_return_val_if_fail (from_codeset != NULL, FALSE); conv = gfls_iconv_new (); if (!gfls_iconv_open (conv, to_codeset, from_codeset, NULL)) { success = FALSE; goto out; } input_buffer = g_bytes_get_data (input_bytes, &input_buffer_size); input_buffer_pos = (gchar *) input_buffer; input_buffer_n_bytes_left = input_buffer_size; conv_result = gfls_iconv_feed_discard_output (conv, &input_buffer_pos, &input_buffer_n_bytes_left, NULL); switch (conv_result) { case GFLS_ICONV_RESULT_OK: case GFLS_ICONV_RESULT_INCOMPLETE_INPUT: success = TRUE; break; case GFLS_ICONV_RESULT_ERROR: case GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE: case GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL: case GFLS_ICONV_RESULT_LOSSY_CONVERSION: default: success = FALSE; break; } /* TODO: call gfls_iconv_feed_discard_output() with @inbuf and * @inbytes_left set to NULL. (But testing it completely is more * difficult). */ out: gfls_iconv_free (conv); return success; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-encoding-conversion.h000066400000000000000000000014761526404376200275660ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2025-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS G_MODULE_EXPORT GflsValidatedString * gfls_encoding_convert (GBytes *input_bytes, const GflsEncoding *from_encoding, const GflsEncoding *to_encoding, gboolean allow_invalid_bytes, gboolean *lossy_conversion, GError **error); G_MODULE_EXPORT gboolean gfls_encoding_try_convert (GBytes *input_bytes, const gchar *to_codeset, const gchar *from_codeset); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-encoding-converter.c000066400000000000000000000405101526404376200273730ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-config.h" #include "gfls-encoding-converter.h" #include #include "gfls-iconv.h" /** * SECTION:gfls-encoding-converter * @Title: GflsEncodingConverter * @Short_description: Character encoding converter * * A utility class to convert from one character encoding to another. * * A #GflsEncodingConverter object can be used only for one conversion. Call the * functions in this order: * - gfls_encoding_converter_new() * - gfls_encoding_converter_set_allow_invalid_bytes() * - gfls_encoding_converter_set_callback() to get the output. * - gfls_encoding_converter_open() * - gfls_encoding_converter_feed(), several times if streaming is desired. * - gfls_encoding_converter_finish_feeding() * - Finally gfls_encoding_converter_get_lossy_conversion() can be called to * know more about how the conversion was performed. */ /* 8 KiB */ #define OUTPUT_BUFFER_SIZE (8192) typedef struct { /* Points to the beginning of the buffer data. */ guint8 *data; /* Points to the current position in @data. */ guint8 *position; /* The total size of the memory allocation of @data. */ gsize size; /* Whether @data needs to be freed. */ guint free_data : 1; } InputBuffer; typedef struct { /* Points to the beginning of the buffer data. */ guint8 *data; /* Points to the current position in @data. */ guint8 *position; /* The total size of the memory allocation of @data. * It must be possible to nul-terminate @data. */ gsize size; } OutputBuffer; struct _GflsEncodingConverterPrivate { GflsIconv *conv; GflsEncodingConverterCallback callback; gpointer callback_data; GBytes *incomplete_input_bytes; guint allow_invalid_bytes : 1; guint lossy_conversion : 1; }; G_DEFINE_TYPE_WITH_PRIVATE (GflsEncodingConverter, gfls_encoding_converter, G_TYPE_OBJECT) static InputBuffer * input_buffer_new_static (const guint8 *data, gsize size) { InputBuffer *input_buffer; input_buffer = g_new0 (InputBuffer, 1); input_buffer->data = (guint8 *) data; input_buffer->position = (guint8 *) data; input_buffer->size = size; input_buffer->free_data = FALSE; return input_buffer; } static InputBuffer * input_buffer_new_full (GflsEncodingConverter *converter, const guint8 *new_data, gsize new_data_size) { const guint8 *previous_data = NULL; gsize previous_data_size = 0; InputBuffer *input_buffer; gsize total_size; if (converter->priv->incomplete_input_bytes != NULL) { previous_data = g_bytes_get_data (converter->priv->incomplete_input_bytes, &previous_data_size); } if (previous_data_size == 0) { g_bytes_unref (converter->priv->incomplete_input_bytes); converter->priv->incomplete_input_bytes = NULL; return input_buffer_new_static (new_data, new_data_size); } input_buffer = g_new0 (InputBuffer, 1); total_size = previous_data_size + new_data_size; input_buffer->data = g_malloc (total_size); /* Concatenation */ memcpy (input_buffer->data, previous_data, previous_data_size); memcpy (input_buffer->data + previous_data_size, new_data, new_data_size); input_buffer->position = input_buffer->data; input_buffer->size = total_size; input_buffer->free_data = TRUE; g_bytes_unref (converter->priv->incomplete_input_bytes); converter->priv->incomplete_input_bytes = NULL; return input_buffer; } static void input_buffer_free (InputBuffer *input_buffer) { if (input_buffer != NULL) { if (input_buffer->free_data) { g_free (input_buffer->data); } g_free (input_buffer); } } static gsize input_buffer_get_n_bytes_left (InputBuffer *input_buffer) { gsize n_bytes_consumed; n_bytes_consumed = input_buffer->position - input_buffer->data; return input_buffer->size - n_bytes_consumed; } static OutputBuffer * output_buffer_new (void) { OutputBuffer *output_buffer; output_buffer = g_new0 (OutputBuffer, 1); output_buffer->data = g_malloc (OUTPUT_BUFFER_SIZE); output_buffer->position = output_buffer->data; output_buffer->size = OUTPUT_BUFFER_SIZE; return output_buffer; } static void output_buffer_free (OutputBuffer *output_buffer) { if (output_buffer != NULL) { g_free (output_buffer->data); g_free (output_buffer); } } static GBytes * output_buffer_free_to_bytes (OutputBuffer *output_buffer) { gsize n_bytes_written; GBytes *bytes; n_bytes_written = output_buffer->position - output_buffer->data; if (n_bytes_written == 0) { output_buffer_free (output_buffer); return NULL; } /* Nul-terminate the buffer. */ output_buffer->position[0] = '\0'; /* Re-alloc at the right size to not consume more memory than necessary. */ output_buffer->data = g_realloc (output_buffer->data, n_bytes_written + 1); bytes = g_bytes_new_take (output_buffer->data, n_bytes_written); g_free (output_buffer); return bytes; } /* Does *not* include the terminating nullable byte. */ static gsize output_buffer_get_n_bytes_left (OutputBuffer *output_buffer) { gsize n_bytes_written; n_bytes_written = output_buffer->position - output_buffer->data; return output_buffer->size - n_bytes_written - 1; } static GflsIconvResult my_iconv_feed (GflsIconv *conv, InputBuffer *input_buffer, OutputBuffer *output_buffer, GError **error) { gchar *input_buffer_pos; gsize input_buffer_n_bytes_left; gchar *output_buffer_pos; gsize output_buffer_n_bytes_left; GflsIconvResult result; input_buffer_pos = (gchar *) input_buffer->position; input_buffer_n_bytes_left = input_buffer_get_n_bytes_left (input_buffer); output_buffer_pos = (gchar *) output_buffer->position; output_buffer_n_bytes_left = output_buffer_get_n_bytes_left (output_buffer); result = gfls_iconv_feed (conv, &input_buffer_pos, &input_buffer_n_bytes_left, &output_buffer_pos, &output_buffer_n_bytes_left, error); input_buffer->position = (guint8 *) input_buffer_pos; output_buffer->position = (guint8 *) output_buffer_pos; return result; } static GflsIconvResult my_iconv_finish_feeding (GflsIconv *conv, OutputBuffer *output_buffer, GError **error) { gchar *output_buffer_pos; gsize output_buffer_n_bytes_left; GflsIconvResult result; output_buffer_pos = (gchar *) output_buffer->position; output_buffer_n_bytes_left = output_buffer_get_n_bytes_left (output_buffer); result = gfls_iconv_feed (conv, NULL, NULL, &output_buffer_pos, &output_buffer_n_bytes_left, error); output_buffer->position = (guint8 *) output_buffer_pos; return result; } static void send_output (GflsEncodingConverter *converter, GBytes *bytes, gboolean is_valid) { if (converter->priv->callback != NULL && bytes != NULL) { converter->priv->callback (bytes, is_valid, converter->priv->callback_data); } } /* @output_buffer: (transfer full) */ static void send_successfully_converted_output (GflsEncodingConverter *converter, OutputBuffer *output_buffer) { GBytes *output_bytes; output_bytes = output_buffer_free_to_bytes (output_buffer); send_output (converter, output_bytes, TRUE); g_bytes_unref (output_bytes); } static void set_invalid_byte_error (GError **error) { g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, _("An invalid byte has been encountered during character set conversion.")); } static void gfls_encoding_converter_finalize (GObject *object) { GflsEncodingConverter *converter = GFLS_ENCODING_CONVERTER (object); gfls_iconv_free (converter->priv->conv); g_bytes_unref (converter->priv->incomplete_input_bytes); G_OBJECT_CLASS (gfls_encoding_converter_parent_class)->finalize (object); } static void gfls_encoding_converter_class_init (GflsEncodingConverterClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gfls_encoding_converter_finalize; } static void gfls_encoding_converter_init (GflsEncodingConverter *converter) { converter->priv = gfls_encoding_converter_get_instance_private (converter); converter->priv->conv = gfls_iconv_new (); converter->priv->allow_invalid_bytes = TRUE; } /** * gfls_encoding_converter_new: * * Returns: (transfer full): a new #GflsEncodingConverter. * Since: 0.5 */ GflsEncodingConverter * gfls_encoding_converter_new (void) { return g_object_new (GFLS_TYPE_ENCODING_CONVERTER, NULL); } /** * gfls_encoding_converter_get_allow_invalid_bytes: * @converter: a #GflsEncodingConverter. * * Returns: whether invalid bytes are allowed during the conversion. * Since: 0.5 */ gboolean gfls_encoding_converter_get_allow_invalid_bytes (GflsEncodingConverter *converter) { g_return_val_if_fail (GFLS_IS_ENCODING_CONVERTER (converter), TRUE); return converter->priv->allow_invalid_bytes; } /** * gfls_encoding_converter_set_allow_invalid_bytes: * @converter: a #GflsEncodingConverter. * @allow_invalid_bytes: whether to allow invalid bytes. * * Sets whether to allow invalid bytes during the conversion. * * Since: 0.5 */ void gfls_encoding_converter_set_allow_invalid_bytes (GflsEncodingConverter *converter, gboolean allow_invalid_bytes) { g_return_if_fail (GFLS_IS_ENCODING_CONVERTER (converter)); converter->priv->allow_invalid_bytes = allow_invalid_bytes != FALSE; } /** * gfls_encoding_converter_set_callback: (skip) * @converter: a #GflsEncodingConverter. * @callback: function to call back to provide the output. * @user_data: user data to pass to @callback. * * Sets the #GflsEncodingConverterCallback. * * Since: 0.5 */ void gfls_encoding_converter_set_callback (GflsEncodingConverter *converter, GflsEncodingConverterCallback callback, gpointer user_data) { g_return_if_fail (GFLS_IS_ENCODING_CONVERTER (converter)); converter->priv->callback = callback; converter->priv->callback_data = user_data; } /** * gfls_encoding_converter_open: * @converter: a #GflsEncodingConverter. * @from_charset: source charset. * @to_charset: destination charset. * @error: location to a #GError, or %NULL to ignore errors. * * Similar to gfls_iconv_open(). * * Returns: %TRUE on success, %FALSE on error. * Since: 0.5 */ gboolean gfls_encoding_converter_open (GflsEncodingConverter *converter, const gchar *from_charset, const gchar *to_charset, GError **error) { g_return_val_if_fail (GFLS_IS_ENCODING_CONVERTER (converter), FALSE); g_return_val_if_fail (from_charset != NULL, FALSE); g_return_val_if_fail (to_charset != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); return gfls_iconv_open (converter->priv->conv, to_charset, from_charset, error); } /** * gfls_encoding_converter_feed: * @converter: a #GflsEncodingConverter. * @data: input bytes. * @n_bytes: the number of input bytes. * @error: location to a #GError, or %NULL to ignore errors. * * Feeds some input bytes to the @converter. * * Can be called several times (useful for streaming scenarios). * * The output is sent with the #GflsEncodingConverterCallback. * * Returns: %TRUE on success, %FALSE on error. * Since: 0.5 */ gboolean gfls_encoding_converter_feed (GflsEncodingConverter *converter, const guint8 *data, gsize n_bytes, GError **error) { InputBuffer *input_buffer; gboolean success = TRUE; g_return_val_if_fail (GFLS_IS_ENCODING_CONVERTER (converter), FALSE); g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (n_bytes > 0, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); input_buffer = input_buffer_new_full (converter, data, n_bytes); while (input_buffer_get_n_bytes_left (input_buffer) > 0) { OutputBuffer *output_buffer; GflsIconvResult result; output_buffer = output_buffer_new (); result = my_iconv_feed (converter->priv->conv, input_buffer, output_buffer, error); if (result == GFLS_ICONV_RESULT_OK) { send_successfully_converted_output (converter, output_buffer); output_buffer = NULL; } else if (result == GFLS_ICONV_RESULT_ERROR) { output_buffer_free (output_buffer); success = FALSE; break; } else if (result == GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE) { guint8 invalid_data[2]; GBytes *invalid_bytes; if (!converter->priv->allow_invalid_bytes) { set_invalid_byte_error (error); output_buffer_free (output_buffer); success = FALSE; break; } send_successfully_converted_output (converter, output_buffer); output_buffer = NULL; invalid_data[0] = input_buffer->position[0]; invalid_data[1] = '\0'; invalid_bytes = g_bytes_new (invalid_data, 1); send_output (converter, invalid_bytes, FALSE); g_bytes_unref (invalid_bytes); input_buffer->position++; /* The loop continues for the remaining input. */ } else if (result == GFLS_ICONV_RESULT_INCOMPLETE_INPUT) { gsize incomplete_input_size; guint8 *incomplete_input_data; send_successfully_converted_output (converter, output_buffer); output_buffer = NULL; incomplete_input_size = input_buffer_get_n_bytes_left (input_buffer); incomplete_input_data = g_malloc (incomplete_input_size + 1); memcpy (incomplete_input_data, input_buffer->position, incomplete_input_size); /* Nul-terminate the GBytes, to be able to send it as-is * later on if needed. */ incomplete_input_data[incomplete_input_size] = '\0'; g_bytes_unref (converter->priv->incomplete_input_bytes); converter->priv->incomplete_input_bytes = g_bytes_new_take (incomplete_input_data, incomplete_input_size); break; } else if (result == GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL) { send_successfully_converted_output (converter, output_buffer); output_buffer = NULL; /* The loop continues with a new output buffer. */ } else if (result == GFLS_ICONV_RESULT_LOSSY_CONVERSION) { send_successfully_converted_output (converter, output_buffer); output_buffer = NULL; converter->priv->lossy_conversion = TRUE; } } input_buffer_free (input_buffer); return success; } /** * gfls_encoding_converter_finish_feeding: * @converter: a #GflsEncodingConverter. * @error: location to a #GError, or %NULL to ignore errors. * * Finishes the input feeding. * * Note that the #GflsEncodingConverterCallback can be called by this function * too. * * Returns: %TRUE on success, %FALSE on error. * Since: 0.5 */ gboolean gfls_encoding_converter_finish_feeding (GflsEncodingConverter *converter, GError **error) { OutputBuffer *output_buffer; GflsIconvResult result; gboolean success = TRUE; g_return_val_if_fail (GFLS_IS_ENCODING_CONVERTER (converter), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (converter->priv->incomplete_input_bytes != NULL) { if (!converter->priv->allow_invalid_bytes) { set_invalid_byte_error (error); return FALSE; } send_output (converter, converter->priv->incomplete_input_bytes, FALSE); g_bytes_unref (converter->priv->incomplete_input_bytes); converter->priv->incomplete_input_bytes = NULL; } output_buffer = output_buffer_new (); result = my_iconv_finish_feeding (converter->priv->conv, output_buffer, error); if (result == GFLS_ICONV_RESULT_OK) { send_successfully_converted_output (converter, output_buffer); output_buffer = NULL; } else if (result == GFLS_ICONV_RESULT_ERROR) { success = FALSE; } else if (result == GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE || result == GFLS_ICONV_RESULT_INCOMPLETE_INPUT || result == GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL) { g_warn_if_reached (); success = FALSE; } else if (result == GFLS_ICONV_RESULT_LOSSY_CONVERSION) { send_successfully_converted_output (converter, output_buffer); output_buffer = NULL; converter->priv->lossy_conversion = TRUE; } output_buffer_free (output_buffer); if (success) { success = gfls_iconv_close (converter->priv->conv, error); } return success; } /** * gfls_encoding_converter_get_lossy_conversion: * @converter: a #GflsEncodingConverter. * * Returns: whether %GFLS_ICONV_RESULT_LOSSY_CONVERSION was encountered. * Since: 0.5 */ gboolean gfls_encoding_converter_get_lossy_conversion (GflsEncodingConverter *converter) { g_return_val_if_fail (GFLS_IS_ENCODING_CONVERTER (converter), FALSE); return converter->priv->lossy_conversion; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-encoding-converter.h000066400000000000000000000077151526404376200274120ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS #define GFLS_TYPE_ENCODING_CONVERTER (gfls_encoding_converter_get_type ()) #define GFLS_ENCODING_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GFLS_TYPE_ENCODING_CONVERTER, GflsEncodingConverter)) #define GFLS_ENCODING_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GFLS_TYPE_ENCODING_CONVERTER, GflsEncodingConverterClass)) #define GFLS_IS_ENCODING_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GFLS_TYPE_ENCODING_CONVERTER)) #define GFLS_IS_ENCODING_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GFLS_TYPE_ENCODING_CONVERTER)) #define GFLS_ENCODING_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GFLS_TYPE_ENCODING_CONVERTER, GflsEncodingConverterClass)) typedef struct _GflsEncodingConverter GflsEncodingConverter; typedef struct _GflsEncodingConverterClass GflsEncodingConverterClass; typedef struct _GflsEncodingConverterPrivate GflsEncodingConverterPrivate; struct _GflsEncodingConverter { GObject parent; GflsEncodingConverterPrivate *priv; }; struct _GflsEncodingConverterClass { GObjectClass parent_class; }; /** * GflsEncodingConverterCallback: * @bytes: the chunk data. * @is_valid: whether @bytes is a valid chunk. * @user_data: user data. * * This callback function is called when there is an output chunk from the * #GflsEncodingConverter. * * @bytes is always nul-terminated, but this is not included in the #GBytes * length. * * If @is_valid is %TRUE, the chunk has been successfully converted. * * If @is_valid is %FALSE, the @bytes is a copy of the input bytes for which the * conversion failed. Note especially that the @bytes have not been escaped; for * that, you can call a function like gfls_utils_bytes_to_hex_representation(). * * #GflsEncodingConverter makes no attempts to coalesce contiguous chunks of the * same kind. In other words, this callback can be called many times in a row * with the same value for @is_valid. * * You need to either use @bytes directly during the call of this callback, or * increase the reference count to store @bytes for later use. (When the call of * the callback finishes, #GflsEncodingConverter decreases the reference count * of @bytes). * * Since: 0.5 */ typedef void (*GflsEncodingConverterCallback) (GBytes *bytes, gboolean is_valid, gpointer user_data); G_MODULE_EXPORT GType gfls_encoding_converter_get_type (void); G_MODULE_EXPORT GflsEncodingConverter * gfls_encoding_converter_new (void); G_MODULE_EXPORT gboolean gfls_encoding_converter_get_allow_invalid_bytes (GflsEncodingConverter *converter); G_MODULE_EXPORT void gfls_encoding_converter_set_allow_invalid_bytes (GflsEncodingConverter *converter, gboolean allow_invalid_bytes); G_MODULE_EXPORT void gfls_encoding_converter_set_callback (GflsEncodingConverter *converter, GflsEncodingConverterCallback callback, gpointer user_data); G_MODULE_EXPORT gboolean gfls_encoding_converter_open (GflsEncodingConverter *converter, const gchar *from_charset, const gchar *to_charset, GError **error); G_MODULE_EXPORT gboolean gfls_encoding_converter_feed (GflsEncodingConverter *converter, const guint8 *data, gsize n_bytes, GError **error); G_MODULE_EXPORT gboolean gfls_encoding_converter_finish_feeding (GflsEncodingConverter *converter, GError **error); G_MODULE_EXPORT gboolean gfls_encoding_converter_get_lossy_conversion (GflsEncodingConverter *converter); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-encoding.c000066400000000000000000000521651526404376200253770ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2002-2005 - Paolo Maggi * SPDX-FileCopyrightText: 2014-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-config.h" #include "gfls-encoding.h" #include /** * SECTION:gfls-encoding * @Title: GflsEncoding * @Short_description: Character encoding * * The #GflsEncoding boxed type represents a character encoding. * * Note that the text in GTK widgets is always encoded in UTF-8. */ /* API design: * * Why not using a simple string to store a charset? With for example a * GflsEncodingTable singleton to retrieve the information from the table. * An API like that would have some ugliness: * - To compare charsets, g_ascii_strcasecmp() must be used. GflsEncoding hides * that with gfls_encoding_equals(). * - The result of `iconv --list` contains duplicates, for example "UTF8" and * "UTF-8". Since UTF-8 is an important case, GflsEncoding has special cases * and special functions for it: gfls_encoding_new_utf8() and * gfls_encoding_is_utf8(). * * An earlier implementation of this class (the first implementation of * GtkSourceEncoding, which in turn came from gedit) didn't support other * charsets than those listed in the table (plus UTF-8 and the locale encoding). * gtk_source_encoding_get_from_charset() returned NULL in case the charset was * not found. The problem is that the table is not complete, it just contains * common encodings. For GtkSourceEncoding and the implementation of * GtkSourceFileLoader, this was not a problem: the file loader tried each * candidate encoding one by one. But it would be desirable to use an external * library like uchardet to determine the encoding. uchardet returns an * iconv-compatible charset, as a string, which is not guaranteed to be in the * table. So the charset passed to gfls_encoding_new() is copied as-is, to not * loose any information from uchardet. If the table contains that charset, * fine, we also have a name like "Unicode"; otherwise it's not a problem, we * have a GflsEncoding encapsulating the charset. * * It's a boxed type, not a GObject. Because signals are not needed, so a boxed * type is lighter. gfls_encoding_get_all() creates a lot of GflsEncoding's. It * would be slightly more convenient to have ref counting, but GflsEncoding can * be seen as a string: instead of g_strdup() / g_free(), it's * gfls_encoding_copy() / gfls_encoding_free(). */ struct _GflsEncoding { /* Must never be NULL. */ gchar *charset; /* The name stored here must already be translated. * NULL if unknown. */ gchar *translated_name; }; typedef struct _EncodingData EncodingData; struct _EncodingData { const gchar *charset; /* The name stored here is not yet translated and must be translated. */ const gchar *name_to_translate; }; #define UTF8_CANONICAL_FORM "UTF-8" G_DEFINE_BOXED_TYPE (GflsEncoding, gfls_encoding, gfls_encoding_copy, gfls_encoding_free) /* This table should not contain duplicates: iconv supports for example "utf8", * "UTF8", "utf-8" and "UTF-8", they are equivalent (as far as I've tested) but * the table contains only "UTF-8". As a result, a function like * gfls_encoding_get_all() doesn't return duplicates, which is important * to not try several times the same encoding when loading a file, or to not * show duplicated encodings in a GtkComboBox when choosing manually an * encoding. * * The original version of this table comes from profterm. * SPDX-FileCopyrightText: 2002 - Red Hat, Inc. */ static const EncodingData encodings_table[] = { /* UTF-8 first, so that it's the first encoding returned by * gfls_encoding_get_all(). */ { UTF8_CANONICAL_FORM, N_("Unicode") }, { "ISO-8859-1", N_("Western") }, { "ISO-8859-2", N_("Central European") }, { "ISO-8859-3", N_("South European") }, { "ISO-8859-4", N_("Baltic") }, { "ISO-8859-5", N_("Cyrillic") }, { "ISO-8859-6", N_("Arabic") }, { "ISO-8859-7", N_("Greek") }, { "ISO-8859-8", N_("Hebrew Visual") }, { "ISO-8859-9", N_("Turkish") }, { "ISO-8859-10", N_("Nordic") }, { "ISO-8859-13", N_("Baltic") }, { "ISO-8859-14", N_("Celtic") }, { "ISO-8859-15", N_("Western") }, { "ISO-8859-16", N_("Romanian") }, { "UTF-7", N_("Unicode") }, { "UTF-16", N_("Unicode") }, { "UTF-16BE", N_("Unicode") }, { "UTF-16LE", N_("Unicode") }, { "UTF-32", N_("Unicode") }, { "UCS-2", N_("Unicode") }, { "UCS-4", N_("Unicode") }, { "ARMSCII-8", N_("Armenian") }, { "BIG5", N_("Chinese Traditional") }, { "BIG5-HKSCS", N_("Chinese Traditional") }, { "CP866", N_("Cyrillic/Russian") }, { "EUC-JP", N_("Japanese") }, { "EUC-JP-MS", N_("Japanese") }, { "CP932", N_("Japanese") }, { "EUC-KR", N_("Korean") }, { "EUC-TW", N_("Chinese Traditional") }, { "GB18030", N_("Chinese Simplified") }, { "GB2312", N_("Chinese Simplified") }, { "GBK", N_("Chinese Simplified") }, { "GEORGIAN-ACADEMY", N_("Georgian") }, /* FIXME GEOSTD8 ? */ { "IBM850", N_("Western") }, { "IBM852", N_("Central European") }, { "IBM855", N_("Cyrillic") }, { "IBM857", N_("Turkish") }, { "IBM862", N_("Hebrew") }, { "IBM864", N_("Arabic") }, { "ISO-2022-JP", N_("Japanese") }, { "ISO-2022-KR", N_("Korean") }, { "ISO-IR-111", N_("Cyrillic") }, { "JOHAB", N_("Korean") }, { "KOI8R", N_("Cyrillic") }, { "KOI8-R", N_("Cyrillic") }, { "KOI8U", N_("Cyrillic/Ukrainian") }, { "SHIFT_JIS", N_("Japanese") }, { "TCVN", N_("Vietnamese") }, { "TIS-620", N_("Thai") }, { "UHC", N_("Korean") }, { "VISCII", N_("Vietnamese") }, { "WINDOWS-1250", N_("Central European") }, { "WINDOWS-1251", N_("Cyrillic") }, { "WINDOWS-1252", N_("Western") }, { "WINDOWS-1253", N_("Greek") }, { "WINDOWS-1254", N_("Turkish") }, { "WINDOWS-1255", N_("Hebrew") }, { "WINDOWS-1256", N_("Arabic") }, { "WINDOWS-1257", N_("Baltic") }, { "WINDOWS-1258", N_("Vietnamese") } }; static GflsEncoding * _gfls_encoding_new_full (const gchar *charset, const gchar *translated_name) { GflsEncoding *enc; g_assert (charset != NULL); enc = g_new (GflsEncoding, 1); enc->charset = g_strdup (charset); enc->translated_name = g_strdup (translated_name); return enc; } /** * gfls_encoding_copy: * @enc: a #GflsEncoding. * * Returns: (transfer full): a copy of @enc. * Since: 0.5 */ GflsEncoding * gfls_encoding_copy (const GflsEncoding *enc) { g_return_val_if_fail (enc != NULL, NULL); return _gfls_encoding_new_full (enc->charset, enc->translated_name); } /** * gfls_encoding_copy_func: * @src: a #GflsEncoding. * @data: Additional data (ignored). * * A #GCopyFunc provided for convenience. It does the same as * gfls_encoding_copy(). It is useful for example for g_slist_copy_deep(). * * Returns: a copy of @src. * Since: 0.5 */ gpointer gfls_encoding_copy_func (gconstpointer src, gpointer data) { return gfls_encoding_copy (src); } /** * gfls_encoding_free: * @enc: (nullable): a #GflsEncoding, or %NULL. * * Since: 0.5 */ void gfls_encoding_free (GflsEncoding *enc) { if (enc != NULL) { g_free (enc->charset); g_free (enc->translated_name); g_free (enc); } } static gboolean charset_is_utf8 (const gchar *charset) { return (g_ascii_strcasecmp (charset, "UTF-8") == 0 || g_ascii_strcasecmp (charset, "UTF8") == 0); } static gboolean charset_equals (const gchar *charset1, const gchar *charset2) { if (charset_is_utf8 (charset1) && charset_is_utf8 (charset2)) { return TRUE; } return g_ascii_strcasecmp (charset1, charset2) == 0; } static const gchar * get_locale_charset (void) { const gchar *locale_charset; if (g_get_charset (&locale_charset)) { return UTF8_CANONICAL_FORM; } return locale_charset; } static const gchar * get_translated_name (const gchar *charset) { guint i; for (i = 0; i < G_N_ELEMENTS (encodings_table); i++) { const EncodingData *cur_data = encodings_table + i; if (charset_equals (cur_data->charset, charset)) { return _(cur_data->name_to_translate); } } /* If setlocale (LC_ALL, ""); is *not* called early in main(), we can * get "ANSI_X3.4-1968" as the locale charset. * (If setlocale (LC_ALL, ""); *is* called, we normally get "UTF-8" as * the locale charset). */ if (charset_equals (charset, "ANSI_X3.4-1968")) { /* US-ASCII is an equivalent charset. Since it's a charset, we * do not translate it. */ return "US-ASCII"; } return NULL; } /** * gfls_encoding_new: * @charset: a character set. * * Creates a new #GflsEncoding from a character set such as "UTF-8" or * "ISO-8859-1". * * The gfls_encoding_get_charset() function will return exactly the same string * as the @charset passed in to this constructor. * * Returns: (transfer full): the new #GflsEncoding. Free with * gfls_encoding_free(). * Since: 0.5 */ GflsEncoding * gfls_encoding_new (const gchar *charset) { const gchar *translated_name; g_return_val_if_fail (charset != NULL, NULL); translated_name = get_translated_name (charset); return _gfls_encoding_new_full (charset, translated_name); } /** * gfls_encoding_new_utf8: * * Creates a new #GflsEncoding with the "UTF-8" character set. * * Returns: (transfer full): the new #GflsEncoding. Free with * gfls_encoding_free(). * Since: 0.5 */ GflsEncoding * gfls_encoding_new_utf8 (void) { return gfls_encoding_new (UTF8_CANONICAL_FORM); } /** * gfls_encoding_new_from_locale: * * Creates a new #GflsEncoding from the current locale, as returned by * g_get_charset(). * * Returns: (transfer full): the new #GflsEncoding. Free with * gfls_encoding_free(). * Since: 0.5 */ GflsEncoding * gfls_encoding_new_from_locale (void) { return gfls_encoding_new (get_locale_charset ()); } /** * gfls_encoding_get_charset: * @enc: a #GflsEncoding. * * Gets the character set of the #GflsEncoding, such as "UTF-8" or "ISO-8859-1". * * Returns: the character set of the #GflsEncoding. * Since: 0.5 */ const gchar * gfls_encoding_get_charset (const GflsEncoding *enc) { g_return_val_if_fail (enc != NULL, NULL); g_assert (enc->charset != NULL); return enc->charset; } /** * gfls_encoding_has_known_charset: * @enc: a #GflsEncoding. * * Returns %TRUE if @enc has a charset known by #GflsEncoding. In other words: * if @enc is equal to an encoding returned by gfls_encoding_get_all(). * * When the charset string comes from an untrusted source, it can be desirable * to check it. * * Returns: whether @enc has a charset known by #GflsEncoding. * Since: 0.5 */ gboolean gfls_encoding_has_known_charset (const GflsEncoding *enc) { guint i; g_return_val_if_fail (enc != NULL, FALSE); g_assert (enc->charset != NULL); if (charset_equals (enc->charset, get_locale_charset ())) { /* Even if the locale charset is not in the table, it is * desirable to treat it as 'known': at least it should work * with iconv, and it comes from a trusted source. */ return TRUE; } for (i = 0; i < G_N_ELEMENTS (encodings_table); i++) { const EncodingData *cur_data = encodings_table + i; if (charset_equals (cur_data->charset, enc->charset)) { return TRUE; } } return FALSE; } /** * gfls_encoding_get_name: * @enc: a #GflsEncoding. * * Gets the name of the #GflsEncoding such as "Unicode" or "Western". If the * charset is unknown by #GflsEncoding, "Unknown" is returned. The return value * is already translated by gettext. * * Returns: the name of the #GflsEncoding. * Since: 0.5 */ const gchar * gfls_encoding_get_name (const GflsEncoding *enc) { g_return_val_if_fail (enc != NULL, NULL); return (enc->translated_name != NULL) ? enc->translated_name : _("Unknown"); } /** * gfls_encoding_to_string: * @enc: a #GflsEncoding. * * Returns the encoding name with the charset in parenthesis, for example * "Unicode (UTF-8)". If the name is unknown, just the charset is returned. The * name is translated by gettext. * * Returns: a string representation. Free with g_free() when no longer needed. * Since: 0.5 */ gchar * gfls_encoding_to_string (const GflsEncoding *enc) { g_return_val_if_fail (enc != NULL, NULL); g_assert (enc->charset != NULL); if (enc->translated_name != NULL) { return g_strdup_printf ("%s (%s)", enc->translated_name, enc->charset); } return g_strdup (enc->charset); } /** * gfls_encoding_is_utf8: * @enc: a #GflsEncoding. * * Returns whether @enc is a UTF-8 encoding. * * If @enc was created with gfls_encoding_new_utf8(), the charset is "UTF-8". * But iconv supports other variants: "UTF8", "utf-8" and "utf8". This function * returns %TRUE for all UTF-8 variants supported by iconv. * * Returns: whether @enc is a UTF-8 encoding. * Since: 0.5 */ gboolean gfls_encoding_is_utf8 (const GflsEncoding *enc) { g_return_val_if_fail (enc != NULL, FALSE); g_assert (enc->charset != NULL); return charset_is_utf8 (enc->charset); } /** * gfls_encoding_is_locale: * @enc: a #GflsEncoding. * * Returns: whether @enc is the locale encoding (see * gfls_encoding_new_from_locale()). * Since: 0.5 */ gboolean gfls_encoding_is_locale (const GflsEncoding *enc) { g_return_val_if_fail (enc != NULL, FALSE); g_assert (enc->charset != NULL); return charset_equals (enc->charset, get_locale_charset ()); } /** * gfls_encoding_equals: * @enc1: (nullable): a #GflsEncoding, or %NULL. * @enc2: (nullable): a #GflsEncoding, or %NULL. * * Returns whether @enc1 and @enc2 are equal. It returns %TRUE if and only if: * - Both @enc1 and @enc2 are %NULL; * - Or both @enc1 and @enc2 have a UTF-8 charset (see * gfls_encoding_is_utf8()); * - Or the charsets are equal according to g_ascii_strcasecmp() (because * iconv-compatible charsets are case insensitive). * * Returns: whether @enc1 and @enc2 are equal. * Since: 0.5 */ gboolean gfls_encoding_equals (const GflsEncoding *enc1, const GflsEncoding *enc2) { if (enc1 == NULL || enc2 == NULL) { return enc1 == NULL && enc2 == NULL; } g_assert (enc1->charset != NULL); g_assert (enc2->charset != NULL); return charset_equals (enc1->charset, enc2->charset); } /** * gfls_encoding_compare_func: * @a: (nullable): a #GflsEncoding. * @b: (nullable): a #GflsEncoding. * * A #GCompareFunc provided for convenience. When 0 is returned it means that * the two encodings are equal according to gfls_encoding_equals(). * * It is useful for example for g_slist_find_custom(). * * Returns: an integer according to #GCompareFunc. * Since: 0.5 */ gint gfls_encoding_compare_func (gconstpointer a, gconstpointer b) { const GflsEncoding *enc_a = a; const GflsEncoding *enc_b = b; if (gfls_encoding_equals (enc_a, enc_b)) { return 0; } /* Handle NULL gracefully by sorting it before non-NULL encodings. * Like g_strcmp0() is for strings. */ if (enc_a == NULL) { return -1; } if (enc_b == NULL) { return 1; } /* Another possibility would be to do the comparison on the return * values of gfls_encoding_to_string(), but this is slightly more * costly, and what matters most is when enc_a and enc_b are *equal*. */ return g_strcmp0 (enc_a->charset, enc_b->charset); } static gboolean present_in_list (GSList *list, const GflsEncoding *enc) { return g_slist_find_custom (list, enc, gfls_encoding_compare_func) != NULL; } /** * gfls_encoding_get_all: * * Gets a list of all encodings known by #GflsEncoding. * * Returns: (transfer full) (element-type GflsEncoding): a list of * #GflsEncoding's. * Since: 0.5 */ GSList * gfls_encoding_get_all (void) { GSList *list = NULL; GflsEncoding *locale_enc; gint i; for (i = G_N_ELEMENTS (encodings_table) - 1; i >= 0; i--) { const EncodingData *cur_data = encodings_table + i; GflsEncoding *enc; enc = _gfls_encoding_new_full (cur_data->charset, _(cur_data->name_to_translate)); list = g_slist_prepend (list, enc); } /* Add locale encoding first. */ locale_enc = gfls_encoding_new_from_locale (); if (present_in_list (list, locale_enc)) { gfls_encoding_free (locale_enc); } else { list = g_slist_prepend (list, locale_enc); } return list; } static GSList * remove_duplicates_keep_first (GSList *list) { GSList *new_list = NULL; GSList *l; for (l = list; l != NULL; l = l->next) { GflsEncoding *cur_enc = l->data; if (present_in_list (new_list, cur_enc)) { gfls_encoding_free (cur_enc); } else { new_list = g_slist_prepend (new_list, cur_enc); } } new_list = g_slist_reverse (new_list); g_slist_free (list); return new_list; } static GSList * remove_duplicates_keep_last (GSList *list) { GSList *new_list = NULL; GSList *l; list = g_slist_reverse (list); for (l = list; l != NULL; l = l->next) { GflsEncoding *cur_enc = l->data; if (present_in_list (new_list, cur_enc)) { gfls_encoding_free (cur_enc); } else { new_list = g_slist_prepend (new_list, cur_enc); } } g_slist_free (list); return new_list; } /** * gfls_encoding_remove_duplicates: * @list: (transfer full) (element-type GflsEncoding): a list of * #GflsEncoding's. * @removal_type: the #GflsEncodingDuplicates. * * A convenience function to remove duplicated encodings in a list. * * Returns: (transfer full) (element-type GflsEncoding): the new start of * the #GSList. * Since: 0.5 */ GSList * gfls_encoding_remove_duplicates (GSList *list, GflsEncodingDuplicates removal_type) { switch (removal_type) { case GFLS_ENCODING_DUPLICATES_KEEP_FIRST: return remove_duplicates_keep_first (list); case GFLS_ENCODING_DUPLICATES_KEEP_LAST: return remove_duplicates_keep_last (list); default: break; } g_return_val_if_reached (list); } /* Returns: (transfer full) (element-type GflsEncoding). */ static GSList * default_candidates_strv_to_list (const gchar * const *enc_str) { GSList *list = NULL; gchar **p; for (p = (gchar **)enc_str; p != NULL && *p != NULL; p++) { const gchar *charset = *p; GflsEncoding *enc; if (g_str_equal (charset, "CURRENT")) { enc = gfls_encoding_new_from_locale (); } else { enc = gfls_encoding_new (charset); } if (present_in_list (list, enc)) { gfls_encoding_free (enc); continue; } /* If the translator has not translated correctly the list of * default candidate encodings, ensure that it won't trigger a * file loading error. */ if (!gfls_encoding_has_known_charset (enc)) { g_warning ("GflsEncoding: unknown charset '%s', " "ignoring it for the default candidates.", charset); gfls_encoding_free (enc); continue; } list = g_slist_prepend (list, enc); } return g_slist_reverse (list); } /** * gfls_encoding_get_default_candidates: * * Gets the list of default candidate encodings to try when loading a file. * * This function returns a different list depending on the current locale (i.e., * language, country and default encoding). The UTF-8 encoding and the current * locale encoding are guaranteed to be present in the returned list. * * Note that the returned list doesn't contain all encodings known by * #GflsEncoding, it is a limited list that contains only the encodings that * have the most likelihood to fit for the current locale. * * Returns: (transfer full) (element-type GflsEncoding): the list of default * candidate encodings. * Since: 0.5 */ GSList * gfls_encoding_get_default_candidates (void) { const gchar *encodings_str; const gchar *encodings_str_translated; GVariant *encodings_variant; const gchar **encodings_strv; GSList *encodings_list; GError *error = NULL; /* Translators: This is the sorted list of encodings used by * libgedit-gfls for automatic detection of the file encoding. You may * want to customize it adding encodings that are common in your * country, for instance the GB18030 encoding for the Chinese * translation. You may also want to remove the ISO-8859-15 encoding * (covering English and most Western European languages) if you think * people in your country will rarely use it. 'CURRENT' is a magic value * used by libgedit-gfls and it represents the encoding for the current * locale, so please don't translate the 'CURRENT' term. Keep the same * format: square brackets, single quotes, commas. */ encodings_str = N_("['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']"); encodings_str_translated = _(encodings_str); encodings_variant = g_variant_parse (G_VARIANT_TYPE_STRING_ARRAY, encodings_str_translated, NULL, NULL, &error); if (error != NULL) { const gchar * const *language_names = g_get_language_names (); g_warning ("Error while parsing encodings list for locale %s:\n" "Translated list: %s\n" "Error message: %s", language_names[0], encodings_str_translated, error->message); g_clear_error (&error); encodings_variant = g_variant_parse (G_VARIANT_TYPE_STRING_ARRAY, encodings_str, NULL, NULL, &error); g_assert_no_error (error); } g_variant_ref_sink (encodings_variant); encodings_strv = g_variant_get_strv (encodings_variant, NULL); encodings_list = default_candidates_strv_to_list (encodings_strv); g_free ((gpointer) encodings_strv); /* Ensure that UTF-8 and CURRENT are present. */ encodings_list = g_slist_prepend (encodings_list, gfls_encoding_new_from_locale ()); encodings_list = g_slist_prepend (encodings_list, gfls_encoding_new_utf8 ()); encodings_list = gfls_encoding_remove_duplicates (encodings_list, GFLS_ENCODING_DUPLICATES_KEEP_LAST); g_variant_unref (encodings_variant); return encodings_list; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-encoding.h000066400000000000000000000045521526404376200254010ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2002-2005 - Paolo Maggi * SPDX-FileCopyrightText: 2014-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS #define GFLS_TYPE_ENCODING (gfls_encoding_get_type ()) typedef struct _GflsEncoding GflsEncoding; /** * GflsEncodingDuplicates: * @GFLS_ENCODING_DUPLICATES_KEEP_FIRST: Keep the first occurrence. * @GFLS_ENCODING_DUPLICATES_KEEP_LAST: Keep the last occurrence. * * Specifies which #GflsEncoding occurrence to keep when removing duplicated * encodings in a list with gfls_encoding_remove_duplicates(). * * Since: 0.5 */ typedef enum { GFLS_ENCODING_DUPLICATES_KEEP_FIRST, GFLS_ENCODING_DUPLICATES_KEEP_LAST } GflsEncodingDuplicates; G_MODULE_EXPORT GType gfls_encoding_get_type (void); G_MODULE_EXPORT GflsEncoding * gfls_encoding_new (const gchar *charset); G_MODULE_EXPORT GflsEncoding * gfls_encoding_new_utf8 (void); G_MODULE_EXPORT GflsEncoding * gfls_encoding_new_from_locale (void); G_MODULE_EXPORT GflsEncoding * gfls_encoding_copy (const GflsEncoding *enc); G_MODULE_EXPORT gpointer gfls_encoding_copy_func (gconstpointer src, gpointer data); G_MODULE_EXPORT void gfls_encoding_free (GflsEncoding *enc); G_MODULE_EXPORT const gchar * gfls_encoding_get_charset (const GflsEncoding *enc); G_MODULE_EXPORT gboolean gfls_encoding_has_known_charset (const GflsEncoding *enc); G_MODULE_EXPORT const gchar * gfls_encoding_get_name (const GflsEncoding *enc); G_MODULE_EXPORT gchar * gfls_encoding_to_string (const GflsEncoding *enc); G_MODULE_EXPORT gboolean gfls_encoding_is_utf8 (const GflsEncoding *enc); G_MODULE_EXPORT gboolean gfls_encoding_is_locale (const GflsEncoding *enc); G_MODULE_EXPORT gboolean gfls_encoding_equals (const GflsEncoding *enc1, const GflsEncoding *enc2); G_MODULE_EXPORT gint gfls_encoding_compare_func (gconstpointer a, gconstpointer b); G_MODULE_EXPORT GSList * gfls_encoding_get_all (void); G_MODULE_EXPORT GSList * gfls_encoding_get_default_candidates (void); G_MODULE_EXPORT GSList * gfls_encoding_remove_duplicates (GSList *list, GflsEncodingDuplicates removal_type); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-error.c000066400000000000000000000021711526404376200247320ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024-2025 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-config.h" #include "gfls-error.h" #include GQuark gfls_loader_error_quark (void) { static GQuark quark = 0; if (G_UNLIKELY (quark == 0)) { quark = g_quark_from_static_string ("gfls-loader-error"); } return quark; } GError * _gfls_loader_error_too_big_file_size (void) { return g_error_new_literal (GFLS_LOADER_ERROR, GFLS_LOADER_ERROR_TOO_BIG, _("The size of the file is too big.")); } GError * _gfls_loader_error_too_big_read (void) { return g_error_new_literal (GFLS_LOADER_ERROR, GFLS_LOADER_ERROR_TOO_BIG, _("Limit on the number of bytes to read reached.")); } GError * _gfls_loader_error_not_utf8 (void) { return g_error_new_literal (GFLS_LOADER_ERROR, GFLS_LOADER_ERROR_NOT_UTF8, _("The content is not encoded in UTF-8.")); } GError * _gfls_loader_error_has_very_long_line (void) { return g_error_new_literal (GFLS_LOADER_ERROR, GFLS_LOADER_ERROR_HAS_VERY_LONG_LINE, _("The content contains a very long line.")); } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-error.h000066400000000000000000000024021526404376200247340ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024-2025 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_ERROR_H #define GFLS_ERROR_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS #define GFLS_LOADER_ERROR gfls_loader_error_quark () /** * GflsLoaderError: * @GFLS_LOADER_ERROR_TOO_BIG: The content is too big. * @GFLS_LOADER_ERROR_NOT_UTF8: The content is not a valid UTF-8 string. Used by * basic loaders that don't support charset conversion. * @GFLS_LOADER_ERROR_HAS_VERY_LONG_LINE: The content contains a very long line. * * An error code used with the %GFLS_LOADER_ERROR domain. * * Since: 0.1 */ typedef enum _GflsLoaderError { GFLS_LOADER_ERROR_TOO_BIG, GFLS_LOADER_ERROR_NOT_UTF8, GFLS_LOADER_ERROR_HAS_VERY_LONG_LINE, } GflsLoaderError; G_MODULE_EXPORT GQuark gfls_loader_error_quark (void); G_GNUC_INTERNAL GError * _gfls_loader_error_too_big_file_size (void); G_GNUC_INTERNAL GError * _gfls_loader_error_too_big_read (void); G_GNUC_INTERNAL GError * _gfls_loader_error_not_utf8 (void); G_GNUC_INTERNAL GError * _gfls_loader_error_has_very_long_line (void); G_END_DECLS #endif /* GFLS_ERROR_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-iconv.c000066400000000000000000000224321526404376200247210ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2019, 2025 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-config.h" #include "gfls-iconv.h" #include #include /** * SECTION:gfls-iconv * @Title: GflsIconv * @Short_description: To use iconv more comfortably * * #GflsIconv is a small wrapper for the g_iconv() family of functions, to * use iconv more comfortably. #GflsIconv returns #GError's and enum values * for the different situations. * * Note that this library also contains the higher-level #GflsEncodingConverter * utility class. * * Call the functions in this order: * - gfls_iconv_new() * - gfls_iconv_open() * - gfls_iconv_feed() in a loop. * - gfls_iconv_feed() with @inbuf and @inbytes_left set to %NULL (in a * loop too if the output buffer is full). * - gfls_iconv_close() * - gfls_iconv_free() * * Note that GLib provides the g_convert() family of functions. As the * g_convert() documentation explains, it is necessary to use g_iconv() (or * #GflsIconv) for streaming conversions. One other use-case is to have * more control over invalid characters: in the case of the * libgedit-gtksourceview library, it is desirable to apply a #GtkTextTag to * them. * * # Avoid iconv if possible * * However, if you have the choice, don't use iconv! It's a crappy API and has * several design flaws (and #GflsIconv cannot fix them): * - When `iconv()` returns `(size_t)-1` (e.g., when the output buffer is full), * we don't know if it has performed lossy conversions. In a normal situation, * the number of lossy conversions performed is returned by `iconv()` as its * return value. * * To fix this flaw, an `iconv2()` function could return the number of lossy * conversions performed as an output parameter. And also an * `iconv_open2` `()` function could take a flags parameter to configure * whether lossy conversions are allowed. * * - The `EILSEQ` error returned by `iconv()` can mean two different things: * there is either an invalid character in the input buffer (so invalid wrt. * the *origin* codeset), or there is a valid character in the input buffer * that cannot be represented in the *target* codeset. * * To fix this flaw, an `iconv2()` function could simply return two different * error codes. * * - When the `EILSEQ` error is returned by `iconv()`, “`*inbuf` is left * pointing to the beginning of the invalid multibyte sequence”, however we * don't know the length of the multibyte sequence! So in practice we assume * only one invalid byte, and call `iconv()` again with `inbuf` pointing to * the next byte, which may fail again, and so on. * * An `iconv2()` function would need a more elaborate API to return this kind * of information. For example by returning/filling a struct as an optional * output parameter. * * Additionally, `iconv()` has different implementations (so working code on * Linux can behave differently on a BSD or Solaris). */ #define CLOSED_CONV_DESCRIPTOR ((GIConv) -1) struct _GflsIconv { GIConv conv_descriptor; }; static gboolean is_opened (GflsIconv *conv) { return conv->conv_descriptor != CLOSED_CONV_DESCRIPTOR; } /** * gfls_iconv_new: (skip) * * Returns: (transfer full): a new #GflsIconv. * Since: 0.4 */ GflsIconv * gfls_iconv_new (void) { GflsIconv *conv; conv = g_new0 (GflsIconv, 1); conv->conv_descriptor = CLOSED_CONV_DESCRIPTOR; return conv; } /** * gfls_iconv_open: (skip) * @conv: a #GflsIconv. * @to_codeset: destination codeset. * @from_codeset: source codeset. * @error: location to a #GError, or %NULL to ignore errors. * * Similar to g_iconv_open(). The difference is that it returns a #GError * instead of `errno`. * * Returns: %TRUE on success, %FALSE on error. * Since: 0.4 */ gboolean gfls_iconv_open (GflsIconv *conv, const gchar *to_codeset, const gchar *from_codeset, GError **error) { g_return_val_if_fail (conv != NULL, FALSE); g_return_val_if_fail (to_codeset != NULL, FALSE); g_return_val_if_fail (from_codeset != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (!is_opened (conv), FALSE); conv->conv_descriptor = g_iconv_open (to_codeset, from_codeset); if (conv->conv_descriptor == CLOSED_CONV_DESCRIPTOR) { gint saved_errno = errno; errno = 0; if (saved_errno == EINVAL) { g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION, _("Conversion from character set “%s” to “%s” is not supported."), from_codeset, to_codeset); } else { g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, _("Failed to open a character set converter from “%s” to “%s”: %s"), from_codeset, to_codeset, g_strerror (saved_errno)); } return FALSE; } return TRUE; } /** * gfls_iconv_feed: (skip) * @conv: a #GflsIconv. * @inbuf: (nullable): bytes to convert. * @inbytes_left: (nullable) (inout): bytes remaining to convert in @inbuf. * @outbuf: (not nullable): converted output bytes. * @outbytes_left: (not nullable) (inout): bytes available to fill in @outbuf. * @error: location to a #GError, or %NULL to ignore errors. * * Similar to g_iconv(). This function reads the `errno` value and converts it * either to a #GError, or to a #GflsIconvResult enumeration value. * * @error is set only when %GFLS_ICONV_RESULT_ERROR is returned. * * Returns: a #GflsIconvResult enumeration value. * Since: 0.4 */ GflsIconvResult gfls_iconv_feed (GflsIconv *conv, gchar **inbuf, gsize *inbytes_left, gchar **outbuf, gsize *outbytes_left, GError **error) { gsize iconv_ret; g_return_val_if_fail (conv != NULL, FALSE); g_return_val_if_fail (outbuf != NULL, FALSE); g_return_val_if_fail (outbytes_left != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); iconv_ret = g_iconv (conv->conv_descriptor, inbuf, inbytes_left, outbuf, outbytes_left); if (iconv_ret == (gsize)-1) { gint saved_errno = errno; errno = 0; if (saved_errno == EILSEQ) { return GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE; } else if (saved_errno == EINVAL) { return GFLS_ICONV_RESULT_INCOMPLETE_INPUT; } else if (saved_errno == E2BIG) { return GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL; } else { g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, _("Error during character set conversion: %s"), g_strerror (saved_errno)); return GFLS_ICONV_RESULT_ERROR; } } else if (iconv_ret > 0) { /* Note: in the other cases above (e.g., buffer full), how to * know if iconv() has performed lossy conversions before * encountering the error condition? So the outbuf might contain * lossy conversions without a way to know it! */ return GFLS_ICONV_RESULT_LOSSY_CONVERSION; } return GFLS_ICONV_RESULT_OK; } /** * gfls_iconv_feed_discard_output: (skip) * @conv: a #GflsIconv. * @inbuf: (nullable): bytes to convert. * @inbytes_left: (nullable) (inout): bytes remaining to convert in @inbuf. * @error: location to a #GError, or %NULL to ignore errors. * * Similar to gfls_iconv_feed() but without the output buffer parameters. * * Returns: a #GflsIconvResult enumeration value. * %GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL is never returned by this * function. * Since: 0.4 */ GflsIconvResult gfls_iconv_feed_discard_output (GflsIconv *conv, gchar **inbuf, gsize *inbytes_left, GError **error) { #define OUTPUT_BUFFER_SIZE (1024) gchar output_buffer[OUTPUT_BUFFER_SIZE]; GflsIconvResult result; g_return_val_if_fail (conv != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); do { gchar *output_buffer_pos = output_buffer; gsize output_buffer_n_bytes_left = OUTPUT_BUFFER_SIZE; result = gfls_iconv_feed (conv, inbuf, inbytes_left, &output_buffer_pos, &output_buffer_n_bytes_left, error); } while (result == GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL); return result; #undef OUTPUT_BUFFER_SIZE } /** * gfls_iconv_close: (skip) * @conv: a #GflsIconv. * @error: location to a #GError, or %NULL to ignore errors. * * Similar to g_iconv_close(). The difference is that it returns a #GError * instead of `errno`. * * Returns: %TRUE on success, %FALSE on error. * Since: 0.4 */ gboolean gfls_iconv_close (GflsIconv *conv, GError **error) { g_return_val_if_fail (conv != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (is_opened (conv)) { gint close_ret = g_iconv_close (conv->conv_descriptor); if (close_ret == -1) { gint saved_errno = errno; errno = 0; g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, _("Failed to close the character set converter: %s"), g_strerror (saved_errno)); return FALSE; } conv->conv_descriptor = CLOSED_CONV_DESCRIPTOR; } return TRUE; } /** * gfls_iconv_free: (skip) * @conv: (nullable): a #GflsIconv, or %NULL. * * Closes and frees @conv. * * If you need to know if closing @conv returns an error, call * gfls_iconv_close() explicitly beforehand. * * Since: 0.4 */ void gfls_iconv_free (GflsIconv *conv) { if (conv != NULL) { gfls_iconv_close (conv, NULL); g_free (conv); } } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-iconv.h000066400000000000000000000042601526404376200247250ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2019, 2025 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS typedef struct _GflsIconv GflsIconv; /** * GflsIconvResult: * @GFLS_ICONV_RESULT_OK: Everything OK. * @GFLS_ICONV_RESULT_ERROR: An error occurred. * @GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE: Stopped at an invalid character in * the @inbuf; or the character could not be represented in the target * character set. `*inbuf` is left pointing to the beginning of the invalid or * unconvertible sequence. * @GFLS_ICONV_RESULT_INCOMPLETE_INPUT: The input byte sequence ends with * an incomplete multi-byte character. `*inbuf` is left pointing to the * beginning of the incomplete multi-byte character. * @GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL: The output buffer has no more * room for the next converted character. * @GFLS_ICONV_RESULT_LOSSY_CONVERSION: A number of nonreversible * conversions have been performed. * * Used as the result value of gfls_iconv_feed(). * * Since: 0.4 */ typedef enum { GFLS_ICONV_RESULT_OK, GFLS_ICONV_RESULT_ERROR, GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE, GFLS_ICONV_RESULT_INCOMPLETE_INPUT, GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL, GFLS_ICONV_RESULT_LOSSY_CONVERSION, } GflsIconvResult; G_MODULE_EXPORT GflsIconv * gfls_iconv_new (void); G_MODULE_EXPORT gboolean gfls_iconv_open (GflsIconv *conv, const gchar *to_codeset, const gchar *from_codeset, GError **error); G_MODULE_EXPORT GflsIconvResult gfls_iconv_feed (GflsIconv *conv, gchar **inbuf, gsize *inbytes_left, gchar **outbuf, gsize *outbytes_left, GError **error); G_MODULE_EXPORT GflsIconvResult gfls_iconv_feed_discard_output (GflsIconv *conv, gchar **inbuf, gsize *inbytes_left, GError **error); G_MODULE_EXPORT gboolean gfls_iconv_close (GflsIconv *conv, GError **error); G_MODULE_EXPORT void gfls_iconv_free (GflsIconv *conv); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-init.c000066400000000000000000000024621526404376200245470ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-init.h" #include "gfls-unsaved-document-titles.h" /** * SECTION:gfls-init * @Title: Gfls Initialization and Finalization */ /** * gfls_init: * * Initializes the Gfls library (e.g. for the internationalization). * * This function can be called several times, but is meant to be called at the * beginning of main(), before any other Gfls function call. * * Since: 0.1 */ void gfls_init (void) { } /** * gfls_finalize: * * Free the resources allocated by Gfls. For example it unrefs the singleton * objects. * * It is not mandatory to call this function, it's just to be friendlier to * memory debugging tools. This function is meant to be called at the end of * main(). It can be called several times. * * Since: 0.1 */ void gfls_finalize (void) { static gboolean done = FALSE; /* Unref the singleton only once, even if this function is called * multiple times, to see if a reference is not released correctly. * Normally the singleton have a ref count of 1. If for some reason the * ref count is increased somewhere, it needs to be decreased * accordingly, at the right place. */ if (!done) { _gfls_unsaved_document_titles_unref_default_instance (); done = TRUE; } } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-init.h000066400000000000000000000006511526404376200245520ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_INIT_H #define GFLS_INIT_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS G_MODULE_EXPORT void gfls_init (void); G_MODULE_EXPORT void gfls_finalize (void); G_END_DECLS #endif /* GFLS_INIT_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-input-stream.c000066400000000000000000000271671526404376200262450ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-input-stream.h" /** * SECTION:gfls-input-stream * @Title: GflsInputStream * @Short_description: Additional functions for #GInputStream * * Additional functions for #GInputStream. */ /* Problem with g_file_load_partial_contents_async/finish(): * * From an API point of view, the maximum number of bytes to read is not * provided *initially*, the GFileReadMoreCallback is called at least once. For * example if I try to load a 100MB file with that function, nothing tells me * that I'll be able to restrict it to 20MB (the API doesn't guarantee it). * * gfls_input_stream_read_async/finish() solves this (and works on any * GInputStream, which we need for stdin support). */ typedef struct { /* Buffer to store the bytes read. It needs to contain one more byte at * the end to nul-terminate the string. Note that it can contain nul * bytes inside the content too (whatever is read from the input * stream). */ guint8 *buf; /* The number of bytes currently allocated to @buf. */ gsize buf_size; /* The current position inside @buf where to write the next bytes. * Invariant: buf_pos < buf_size */ gsize buf_pos; /* Max value for @buf_size. */ gsize buf_max_size; /* Can be NULL. */ GflsSimpleProgressCallback progress_callback; gpointer progress_callback_data; /* Boolean to know if the content from the input stream needed to be * truncated because the maximum number of bytes to read has been * reached (and there *is* more content to read). */ guint truncated : 1; } TaskData; /* 8 KiB, a value recommended by g_input_stream_read_bytes(). */ #define CHUNK_SIZE (8192) static void read_next_chunk (GTask *task); static gsize size_safe_add (gsize a, gsize b) { gsize ret; if (g_size_checked_add (&ret, a, b)) { return ret; } return G_MAXSIZE; } static TaskData * task_data_new (gsize expected_size, gsize max_size) { TaskData *task_data; gsize full_expected_size; gsize full_max_size; gsize initial_buf_size; /* +1 to nul-terminate the buffer. */ full_expected_size = size_safe_add (expected_size, 1); full_max_size = size_safe_add (max_size, 1); initial_buf_size = MIN (full_expected_size, full_max_size); task_data = g_new0 (TaskData, 1); task_data->buf = g_malloc (initial_buf_size); task_data->buf_size = initial_buf_size; task_data->buf_pos = 0; task_data->buf_max_size = full_max_size; task_data->truncated = FALSE; return task_data; } static void task_data_free (TaskData *task_data) { if (task_data != NULL) { g_free (task_data->buf); g_free (task_data); } } static gboolean task_data_max_reached (TaskData *task_data) { g_assert (task_data->buf_pos < task_data->buf_max_size); /* When this is true, it's still possible to nul-terminate the buffer. */ return task_data->buf_pos == task_data->buf_max_size - 1; } /* Returns: the new value for @n_bytes_to_write. */ static gsize task_data_prepare_buffer (TaskData *task_data, gsize n_bytes_to_write) { gsize full_n_bytes_to_write; gsize required_buf_size; g_assert (task_data->buf_pos < task_data->buf_size); g_assert (task_data->buf_pos < task_data->buf_max_size); g_assert (task_data->buf_size <= task_data->buf_max_size); /* To be able to add 1 to n_bytes_to_write without the need to check for * integer overflows. */ g_assert (n_bytes_to_write < G_MAXSIZE); full_n_bytes_to_write = n_bytes_to_write + 1; if (!g_size_checked_add (&required_buf_size, task_data->buf_pos, full_n_bytes_to_write)) { g_assert_not_reached (); } if (required_buf_size <= task_data->buf_size) { return n_bytes_to_write; } /* Need to realloc the buffer */ if (required_buf_size <= task_data->buf_max_size) { task_data->buf = g_realloc (task_data->buf, required_buf_size); task_data->buf_size = required_buf_size; return n_bytes_to_write; } task_data->buf = g_realloc (task_data->buf, task_data->buf_max_size); task_data->buf_size = task_data->buf_max_size; return task_data->buf_size - task_data->buf_pos - 1; } static void task_data_nul_terminate_buffer (TaskData *task_data) { task_data->buf[task_data->buf_pos] = '\0'; } static GBytes * task_data_buffer_to_gbytes (TaskData *task_data) { GBytes *bytes; bytes = g_bytes_new_take (task_data->buf, task_data->buf_pos); task_data->buf = NULL; return bytes; } static void finish_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GInputStream *input_stream = G_INPUT_STREAM (source_object); GTask *task = G_TASK (user_data); TaskData *task_data = g_task_get_task_data (task); GError *error = NULL; g_input_stream_close_finish (input_stream, result, &error); if (error != NULL) { g_task_return_error (task, error); g_object_unref (task); return; } task_data_nul_terminate_buffer (task_data); g_task_return_boolean (task, TRUE); g_object_unref (task); } static void finish (GTask *task) { GInputStream *input_stream = G_INPUT_STREAM (g_task_get_source_object (task)); g_input_stream_close_async (input_stream, g_task_get_priority (task), g_task_get_cancellable (task), finish_cb, task); } static void read_past_max_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GInputStream *input_stream = G_INPUT_STREAM (source_object); GTask *task = user_data; TaskData *task_data = g_task_get_task_data (task); GBytes *bytes; GError *error = NULL; bytes = g_input_stream_read_bytes_finish (input_stream, result, &error); if (error != NULL) { g_task_return_error (task, error); g_object_unref (task); return; } if (g_bytes_get_size (bytes) > 0) { task_data->truncated = TRUE; } g_bytes_unref (bytes); finish (task); } static void read_past_max (GTask *task) { GInputStream *input_stream; input_stream = g_task_get_source_object (task); g_input_stream_read_bytes_async (input_stream, 1, g_task_get_priority (task), g_task_get_cancellable (task), read_past_max_cb, task); } static void read_next_chunk_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GInputStream *input_stream = G_INPUT_STREAM (source_object); GTask *task = user_data; GError *error = NULL; gssize n_bytes_read; TaskData *task_data; n_bytes_read = g_input_stream_read_finish (input_stream, result, &error); if (error != NULL) { g_task_return_error (task, error); g_object_unref (task); return; } if (n_bytes_read < 0) { /* Should not happen, already handled with error != NULL, but * have robust code. */ g_task_return_boolean (task, FALSE); g_object_unref (task); return; } task_data = g_task_get_task_data (task); if (n_bytes_read == 0) { finish (task); return; } task_data->buf_pos += n_bytes_read; if (task_data->progress_callback != NULL) { task_data->progress_callback (task_data->buf_pos, task_data->progress_callback_data); } read_next_chunk (task); } static void read_next_chunk (GTask *task) { GInputStream *input_stream; TaskData *task_data; gsize actual_size_to_read; input_stream = g_task_get_source_object (task); task_data = g_task_get_task_data (task); if (task_data_max_reached (task_data)) { read_past_max (task); return; } actual_size_to_read = task_data_prepare_buffer (task_data, CHUNK_SIZE); g_input_stream_read_async (input_stream, task_data->buf + task_data->buf_pos, actual_size_to_read, g_task_get_priority (task), g_task_get_cancellable (task), read_next_chunk_cb, task); } /** * gfls_input_stream_read_async: (skip) * @input_stream: a #GInputStream. * @expected_size: the expected number of bytes contained in @input_stream. * @max_size: the maximum number of bytes to read. * @io_priority: the I/O priority of the request. E.g. %G_PRIORITY_LOW, * %G_PRIORITY_DEFAULT or %G_PRIORITY_HIGH. * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. * @progress_callback: (nullable): function to call back with progress * information, or %NULL if progress information is not needed. * @progress_callback_data: user data to pass to @progress_callback. * @callback: (scope async): a #GAsyncReadyCallback to call when the operation * is finished. * @user_data: user data to pass to @callback. * * This function starts a read operation on @input_stream. It is meant to be * used as the only read operation on @input_stream, to get a #GBytes as a * result, with @max_size as the provided maximum number of bytes to read. * * @expected_size is typically a #GFile size as returned by * g_file_info_get_size(). But note that in that case, the returned #GBytes may * contain a different number of bytes than what was expected (the * TOC/TOU problem: time of check to time of use). @expected_size is used as an * indication to how much memory to allocate initially. * * This function also closes @input_stream after reading the content. * * See the #GAsyncResult documentation to know how to use this function. * * Since: 0.4 */ void gfls_input_stream_read_async (GInputStream *input_stream, gsize expected_size, gsize max_size, gint io_priority, GCancellable *cancellable, GflsSimpleProgressCallback progress_callback, gpointer progress_callback_data, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; TaskData *task_data; g_return_if_fail (G_IS_INPUT_STREAM (input_stream)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); task = g_task_new (input_stream, cancellable, callback, user_data); g_task_set_priority (task, io_priority); task_data = task_data_new (expected_size, max_size); task_data->progress_callback = progress_callback; task_data->progress_callback_data = progress_callback_data; g_task_set_task_data (task, task_data, (GDestroyNotify) task_data_free); read_next_chunk (task); } /** * gfls_input_stream_read_finish: (skip) * @input_stream: a #GInputStream. * @result: a #GAsyncResult. * @is_truncated: will be set to %TRUE if the @input_stream contains more data * to be read, but the maximum number of bytes to read has been reached. * @error: a #GError, or %NULL. * * Finishes an operation started with gfls_input_stream_read_async(). * * If @is_truncated is set to %TRUE, it is not an error (@error is not set), and * a #GBytes is returned. However, since gfls_input_stream_read_async() is * meant to be used as the only read operation on @input_stream, it is an * undefined behavior if you try to read more content from @input_stream. * * The data contained in the resulting #GBytes is always zero-terminated, but * this is not included in the #GBytes length. * * Returns: (transfer full) (nullable): a #GBytes, or %NULL on error. Free with * g_bytes_unref(). * Since: 0.4 */ GBytes * gfls_input_stream_read_finish (GInputStream *input_stream, GAsyncResult *result, gboolean *is_truncated, GError **error) { gboolean ok; g_return_val_if_fail (G_IS_INPUT_STREAM (input_stream), NULL); g_return_val_if_fail (g_task_is_valid (result, input_stream), NULL); g_return_val_if_fail (is_truncated != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); ok = g_task_propagate_boolean (G_TASK (result), error); if (ok) { TaskData *task_data; task_data = g_task_get_task_data (G_TASK (result)); *is_truncated = task_data->truncated; return task_data_buffer_to_gbytes (task_data); } *is_truncated = FALSE; return NULL; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-input-stream.h000066400000000000000000000023051526404376200262350ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS /** * GflsSimpleProgressCallback: * @number: the number. * @user_data: user data. * * Like #GFileProgressCallback but without the total. * * Since: 0.4 */ typedef void (*GflsSimpleProgressCallback) (gsize number, gpointer user_data); G_MODULE_EXPORT void gfls_input_stream_read_async (GInputStream *input_stream, gsize expected_size, gsize max_size, gint io_priority, GCancellable *cancellable, GflsSimpleProgressCallback progress_callback, gpointer progress_callback_data, GAsyncReadyCallback callback, gpointer user_data); G_MODULE_EXPORT GBytes * gfls_input_stream_read_finish (GInputStream *input_stream, GAsyncResult *result, gboolean *is_truncated, GError **error); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-loader-basic.c000066400000000000000000000211651526404376200261320ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023-2025 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-loader-basic.h" #include "gfls-error.h" #include "gfls-input-stream.h" #include "gfls-utf8.h" /** * SECTION:gfls-loader-basic * @Title: GflsLoaderBasic * @Short_description: Basic file loader * * Basic file loader that validates input for GtkTextView purposes: * - Must not exceed a certain size (because all the content of a GtkTextBuffer * is stored in memory). * - Must be valid UTF-8 already (GTK in general accepts only UTF-8 only * strings). * - Must not contain very long lines (not well supported by the GtkTextView * widget, there can be performance problems and freezes). * * So: * - No character encoding auto-detection and/or conversion. * - No workarounds for problems found, just return an error without the * possibility to re-configure the loading. * * But this basic file loader offers a convenient API for the above: #GFile * loading with the intention to put its content into a GtkTextBuffer. */ /* When the file size is unknown, start with 8 KiB. */ #define DEFAULT_FILE_SIZE (8192) typedef struct { /* Config */ gsize max_size; guint max_n_bytes_per_line; /* Intermediate data */ gsize expected_file_size; GInputStream *input_stream; /* Result */ GBytes *bytes; } TaskData; static TaskData * task_data_new (gsize max_size, guint max_n_bytes_per_line) { TaskData *task_data; task_data = g_new0 (TaskData, 1); task_data->max_size = max_size; task_data->max_n_bytes_per_line = max_n_bytes_per_line; return task_data; } static void task_data_free (TaskData *task_data) { if (task_data != NULL) { g_clear_object (&task_data->input_stream); g_clear_pointer (&task_data->bytes, g_bytes_unref); g_free (task_data); } } static void check_bytes (GTask *task) { TaskData *task_data; const gchar *text; gsize n_bytes; task_data = g_task_get_task_data (task); text = g_bytes_get_data (task_data->bytes, &n_bytes); if (!g_utf8_validate_len (text, n_bytes, NULL)) { g_task_return_error (task, _gfls_loader_error_not_utf8 ()); g_object_unref (task); return; } if (gfls_utf8_find_very_long_line (text, task_data->max_n_bytes_per_line) != NULL) { g_task_return_error (task, _gfls_loader_error_has_very_long_line ()); g_object_unref (task); return; } /* Everything OK, finally done. */ g_task_return_boolean (task, TRUE); g_object_unref (task); } static void read_input_stream_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GInputStream *input_stream = G_INPUT_STREAM (source_object); GTask *task = G_TASK (user_data); TaskData *task_data; gboolean is_truncated = FALSE; GError *error = NULL; task_data = g_task_get_task_data (task); g_clear_pointer (&task_data->bytes, g_bytes_unref); task_data->bytes = gfls_input_stream_read_finish (input_stream, result, &is_truncated, &error); if (error != NULL) { g_task_return_error (task, error); g_object_unref (task); return; } if (is_truncated) { /* Free memory as early as possible, especially because it * reached the maximum. */ g_clear_pointer (&task_data->bytes, g_bytes_unref); g_task_return_error (task, _gfls_loader_error_too_big_read ()); g_object_unref (task); return; } check_bytes (task); } static void read_input_stream (GTask *task) { TaskData *task_data = g_task_get_task_data (task); gfls_input_stream_read_async (task_data->input_stream, task_data->expected_file_size, task_data->max_size, g_task_get_priority (task), g_task_get_cancellable (task), NULL, NULL, read_input_stream_cb, task); } static void open_file_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GFile *file = G_FILE (source_object); GTask *task = G_TASK (user_data); GFileInputStream *file_input_stream; TaskData *task_data; GError *error = NULL; file_input_stream = g_file_read_finish (file, result, &error); if (error != NULL) { g_task_return_error (task, error); g_object_unref (task); g_clear_object (&file_input_stream); return; } task_data = g_task_get_task_data (task); g_clear_object (&task_data->input_stream); task_data->input_stream = G_INPUT_STREAM (file_input_stream); read_input_stream (task); } static void open_file (GTask *task) { GFile *file = g_task_get_source_object (task); g_file_read_async (file, g_task_get_priority (task), g_task_get_cancellable (task), open_file_cb, task); } static void query_file_info_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GFile *file = G_FILE (source_object); GTask *task = G_TASK (user_data); TaskData *task_data; GFileInfo *info; GError *error = NULL; info = g_file_query_info_finish (file, result, &error); if (error != NULL) { g_task_return_error (task, error); g_object_unref (task); g_clear_object (&info); return; } task_data = g_task_get_task_data (task); if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)) { task_data->expected_file_size = g_file_info_get_size (info); if (task_data->expected_file_size > task_data->max_size) { g_task_return_error (task, _gfls_loader_error_too_big_file_size ()); g_object_unref (task); g_clear_object (&info); return; } } else { task_data->expected_file_size = DEFAULT_FILE_SIZE; } open_file (task); g_clear_object (&info); } static void query_file_info (GTask *task) { GFile *file = g_task_get_source_object (task); g_file_query_info_async (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, g_task_get_priority (task), g_task_get_cancellable (task), query_file_info_cb, task); } /** * gfls_loader_basic_load_async: * @file: a #GFile. * @max_size: the maximum allowed number of bytes in total. * @max_n_bytes_per_line: the maximum allowed number of bytes per line, as per * gfls_utf8_find_very_long_line(). * @io_priority: the I/O priority of the request. E.g. %G_PRIORITY_LOW, * %G_PRIORITY_DEFAULT or %G_PRIORITY_HIGH. * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. * @callback: (scope async): a #GAsyncReadyCallback to call when the operation * is finished. * @user_data: user data to pass to @callback. * * Starts a basic file loading operation. * * If the @file content is not a valid UTF-8 string, or if the @max_size or * @max_n_bytes_per_line conditions are not satisfied, an error will be returned * without the file content. * * See the #GAsyncResult documentation to know how to use this function. * * Since: 0.1 */ void gfls_loader_basic_load_async (GFile *file, gsize max_size, guint max_n_bytes_per_line, gint io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; TaskData *task_data; g_return_if_fail (G_IS_FILE (file)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); task = g_task_new (file, cancellable, callback, user_data); g_task_set_priority (task, io_priority); task_data = task_data_new (max_size, max_n_bytes_per_line); g_task_set_task_data (task, task_data, (GDestroyNotify) task_data_free); query_file_info (task); } /** * gfls_loader_basic_load_finish: * @file: a #GFile. * @result: a #GAsyncResult. * @error: a #GError, or %NULL. * * Finishes an operation started with gfls_loader_basic_load_async(). * * If everything went well, a #GBytes with the #GFile content (unmodified) is * returned. It is guaranteed to be a valid UTF-8 string. * * Otherwise an error is returned. The %GFLS_LOADER_ERROR domain is used, among * others. * * The data contained in the resulting #GBytes is always zero-terminated, but * this is not included in the #GBytes length. The resulting #GBytes should be * freed with g_bytes_unref() when no longer in use. * * Returns: a #GBytes, or %NULL on error. * Since: 0.1 */ GBytes * gfls_loader_basic_load_finish (GFile *file, GAsyncResult *result, GError **error) { gboolean ok; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (g_task_is_valid (result, file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); ok = g_task_propagate_boolean (G_TASK (result), error); if (ok) { TaskData *task_data; GBytes *bytes; task_data = g_task_get_task_data (G_TASK (result)); bytes = task_data->bytes; task_data->bytes = NULL; return bytes; } return NULL; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-loader-basic.h000066400000000000000000000014771526404376200261430ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_LOADER_BASIC_H #define GFLS_LOADER_BASIC_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS G_MODULE_EXPORT void gfls_loader_basic_load_async (GFile *file, gsize max_size, guint max_n_bytes_per_line, gint io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); G_MODULE_EXPORT GBytes * gfls_loader_basic_load_finish (GFile *file, GAsyncResult *result, GError **error); G_END_DECLS #endif /* GFLS_LOADER_BASIC_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-loader-config-simple.c000066400000000000000000000060051526404376200276010ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-loader-config-simple.h" /** * SECTION:gfls-loader-config-simple * @Title: GflsLoaderConfigSimple * @Short_description: Loader configuration */ struct _GflsLoaderConfigSimplePrivate { GFile *file; GInputStream *input_stream; }; G_DEFINE_TYPE_WITH_PRIVATE (GflsLoaderConfigSimple, gfls_loader_config_simple, G_TYPE_OBJECT) static void gfls_loader_config_simple_dispose (GObject *object) { GflsLoaderConfigSimple *config = GFLS_LOADER_CONFIG_SIMPLE (object); g_clear_object (&config->priv->file); g_clear_object (&config->priv->input_stream); G_OBJECT_CLASS (gfls_loader_config_simple_parent_class)->dispose (object); } static void gfls_loader_config_simple_class_init (GflsLoaderConfigSimpleClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = gfls_loader_config_simple_dispose; } static void gfls_loader_config_simple_init (GflsLoaderConfigSimple *config) { config->priv = gfls_loader_config_simple_get_instance_private (config); } /** * gfls_loader_config_simple_new_from_file: * @file: a #GFile. * * Creates a new #GflsLoaderConfigSimple object with @file for the input * content. * * Returns: (transfer full): a new #GflsLoaderConfigSimple object. * Since: 0.2 */ GflsLoaderConfigSimple * gfls_loader_config_simple_new_from_file (GFile *file) { GflsLoaderConfigSimple *config; g_return_val_if_fail (G_IS_FILE (file), NULL); config = g_object_new (GFLS_TYPE_LOADER_CONFIG_SIMPLE, NULL); config->priv->file = g_object_ref (file); return config; } /** * gfls_loader_config_simple_new_from_stream: * @input_stream: a #GInputStream. * * Creates a new #GflsLoaderConfigSimple object with @input_stream for the input * content. * * To load from stdin, a useful function is * g_application_command_line_get_stdin(). * * Returns: (transfer full): a new #GflsLoaderConfigSimple object. * Since: 0.2 */ GflsLoaderConfigSimple * gfls_loader_config_simple_new_from_stream (GInputStream *input_stream) { GflsLoaderConfigSimple *config; g_return_val_if_fail (G_IS_INPUT_STREAM (input_stream), NULL); config = g_object_new (GFLS_TYPE_LOADER_CONFIG_SIMPLE, NULL); config->priv->input_stream = g_object_ref (input_stream); return config; } /** * gfls_loader_config_simple_get_file: * @config: a #GflsLoaderConfigSimple. * * Returns: (transfer none) (nullable): the #GFile of @config, or %NULL. * Since: 0.2 */ GFile * gfls_loader_config_simple_get_file (GflsLoaderConfigSimple *config) { g_return_val_if_fail (GFLS_IS_LOADER_CONFIG_SIMPLE (config), NULL); return config->priv->file; } /** * gfls_loader_config_simple_get_stream: * @config: a #GflsLoaderConfigSimple. * * Returns: (transfer none) (nullable): the #GInputStream of @config, or %NULL. * Since: 0.2 */ GInputStream * gfls_loader_config_simple_get_stream (GflsLoaderConfigSimple *config) { g_return_val_if_fail (GFLS_IS_LOADER_CONFIG_SIMPLE (config), NULL); return config->priv->input_stream; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-loader-config-simple.h000066400000000000000000000040061526404376200276050ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_LOADER_CONFIG_SIMPLE_H #define GFLS_LOADER_CONFIG_SIMPLE_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS #define GFLS_TYPE_LOADER_CONFIG_SIMPLE (gfls_loader_config_simple_get_type ()) #define GFLS_LOADER_CONFIG_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GFLS_TYPE_LOADER_CONFIG_SIMPLE, GflsLoaderConfigSimple)) #define GFLS_LOADER_CONFIG_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GFLS_TYPE_LOADER_CONFIG_SIMPLE, GflsLoaderConfigSimpleClass)) #define GFLS_IS_LOADER_CONFIG_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GFLS_TYPE_LOADER_CONFIG_SIMPLE)) #define GFLS_IS_LOADER_CONFIG_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GFLS_TYPE_LOADER_CONFIG_SIMPLE)) #define GFLS_LOADER_CONFIG_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GFLS_TYPE_LOADER_CONFIG_SIMPLE, GflsLoaderConfigSimpleClass)) typedef struct _GflsLoaderConfigSimple GflsLoaderConfigSimple; typedef struct _GflsLoaderConfigSimpleClass GflsLoaderConfigSimpleClass; typedef struct _GflsLoaderConfigSimplePrivate GflsLoaderConfigSimplePrivate; struct _GflsLoaderConfigSimple { GObject parent; GflsLoaderConfigSimplePrivate *priv; }; struct _GflsLoaderConfigSimpleClass { GObjectClass parent_class; gpointer padding[12]; }; G_MODULE_EXPORT GType gfls_loader_config_simple_get_type (void); G_MODULE_EXPORT GflsLoaderConfigSimple *gfls_loader_config_simple_new_from_file (GFile *file); G_MODULE_EXPORT GflsLoaderConfigSimple *gfls_loader_config_simple_new_from_stream (GInputStream *input_stream); G_MODULE_EXPORT GFile * gfls_loader_config_simple_get_file (GflsLoaderConfigSimple *config); G_MODULE_EXPORT GInputStream * gfls_loader_config_simple_get_stream (GflsLoaderConfigSimple *config); G_END_DECLS #endif /* GFLS_LOADER_CONFIG_SIMPLE_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-loader-config.c000066400000000000000000000011251526404376200263100ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-loader-config.h" /** * SECTION:gfls-loader-config * @Title: GflsLoaderConfig * @Short_description: Loader configuration interface * * #GflsLoaderConfig is an interface that classes implement to store a loader * configuration. * * Currently it is an empty interface, also called a “marker interface”. */ G_DEFINE_INTERFACE (GflsLoaderConfig, gfls_loader_config, G_TYPE_OBJECT) static void gfls_loader_config_default_init (GflsLoaderConfigInterface *interface) { } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-loader-config.h000066400000000000000000000022671526404376200263250ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_LOADER_CONFIG_H #define GFLS_LOADER_CONFIG_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS #define GFLS_TYPE_LOADER_CONFIG (gfls_loader_config_get_type ()) #define GFLS_LOADER_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GFLS_TYPE_LOADER_CONFIG, GflsLoaderConfig)) #define GFLS_IS_LOADER_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GFLS_TYPE_LOADER_CONFIG)) #define GFLS_LOADER_CONFIG_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GFLS_TYPE_LOADER_CONFIG, GflsLoaderConfigInterface)) typedef struct _GflsLoaderConfig GflsLoaderConfig; typedef struct _GflsLoaderConfigInterface GflsLoaderConfigInterface; /** * GflsLoaderConfigInterface: * @parent_interface: The parent interface. * * Since: 0.2 */ struct _GflsLoaderConfigInterface { GTypeInterface parent_interface; }; G_MODULE_EXPORT GType gfls_loader_config_get_type (void); G_END_DECLS #endif /* GFLS_LOADER_CONFIG_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-unsaved-document-titles.c000066400000000000000000000150351526404376200303670ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-config.h" #include "gfls-unsaved-document-titles.h" #include /** * SECTION:gfls-unsaved-document-titles * @Title: GflsUnsavedDocumentTitles * @Short_description: To give titles to unsaved documents * * #GflsUnsavedDocumentTitles is used to give titles to unsaved documents, such * as "Unsaved Document N" with 'N' replaced by a number. * * This is for new documents that have never been saved before and reside in * memory only. These documents have not yet an associated #GFile. * * Do not confuse it with documents with unsaved changes. */ #define FIRST_NUMBER (1) struct _GflsUnsavedDocumentTitlesPrivate { /* Sorted list of owned 'gint*'. */ GList *allocated_numbers; GflsUnsavedDocumentTitleCallback title_callback; }; static GflsUnsavedDocumentTitles *default_instance; G_DEFINE_TYPE_WITH_PRIVATE (GflsUnsavedDocumentTitles, gfls_unsaved_document_titles, G_TYPE_OBJECT) static gint compare_numbers (gconstpointer a, gconstpointer b) { const gint *ptr_num_a; const gint *ptr_num_b; gint num_a; gint num_b; g_return_val_if_fail (a != NULL, 0); g_return_val_if_fail (b != NULL, 0); ptr_num_a = a; ptr_num_b = b; num_a = *ptr_num_a; num_b = *ptr_num_b; return num_a - num_b; } static gchar * default_title_cb (gint num) { return g_strdup_printf (_("Unsaved Document %d"), num); } static void gfls_unsaved_document_titles_finalize (GObject *object) { GflsUnsavedDocumentTitles *titles = GFLS_UNSAVED_DOCUMENT_TITLES (object); if (default_instance == titles) { default_instance = NULL; } g_list_free_full (titles->priv->allocated_numbers, g_free); G_OBJECT_CLASS (gfls_unsaved_document_titles_parent_class)->finalize (object); } static void gfls_unsaved_document_titles_class_init (GflsUnsavedDocumentTitlesClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gfls_unsaved_document_titles_finalize; } static void gfls_unsaved_document_titles_init (GflsUnsavedDocumentTitles *titles) { titles->priv = gfls_unsaved_document_titles_get_instance_private (titles); titles->priv->title_callback = default_title_cb; } /** * gfls_unsaved_document_titles_new: * * Returns: (transfer full): a new #GflsUnsavedDocumentTitles object. * Since: 0.1 */ GflsUnsavedDocumentTitles * gfls_unsaved_document_titles_new (void) { return g_object_new (GFLS_TYPE_UNSAVED_DOCUMENT_TITLES, NULL); } /** * gfls_unsaved_document_titles_get_default: * * Returns: (transfer none): the default instance of #GflsUnsavedDocumentTitles. * Since: 0.1 */ GflsUnsavedDocumentTitles * gfls_unsaved_document_titles_get_default (void) { if (default_instance == NULL) { default_instance = gfls_unsaved_document_titles_new (); } return default_instance; } void _gfls_unsaved_document_titles_unref_default_instance (void) { if (default_instance != NULL) { g_object_unref (default_instance); } /* default_instance is not set to NULL here, it is set to NULL in * gfls_unsaved_document_titles_finalize() (i.e. when we are sure that * the ref count reaches 0). */ } /** * gfls_unsaved_document_titles_allocate_number: * @titles: a #GflsUnsavedDocumentTitles. * * Allocates a number for an unsaved document. When the document is saved on * disk, you need to give back the number with * gfls_unsaved_document_titles_release_number(). * * The returned number is the lowest available value, starting at 1. * * Returns: the allocated number. * Since: 0.1 */ gint gfls_unsaved_document_titles_allocate_number (GflsUnsavedDocumentTitles *titles) { gint num = FIRST_NUMBER; GList *node; gint *num_data; g_return_val_if_fail (GFLS_IS_UNSAVED_DOCUMENT_TITLES (titles), 0); node = titles->priv->allocated_numbers; while (node != NULL) { const gint *node_data = node->data; const gint allocated_num = *node_data; if (num != allocated_num) { break; } num++; node = node->next; } num_data = g_new (gint, 1); *num_data = num; titles->priv->allocated_numbers = g_list_insert_sorted (titles->priv->allocated_numbers, num_data, compare_numbers); return num; } /** * gfls_unsaved_document_titles_release_number: * @titles: a #GflsUnsavedDocumentTitles. * @number: the number to release. * * Call this function to give back @number to @titles, so that it becomes * available for a next unsaved document. This is usually done when the document * is saved on disk. * * Since: 0.1 */ void gfls_unsaved_document_titles_release_number (GflsUnsavedDocumentTitles *titles, gint number) { GList *node; g_return_if_fail (GFLS_IS_UNSAVED_DOCUMENT_TITLES (titles)); for (node = titles->priv->allocated_numbers; node != NULL; node = node->next) { const gint *node_data = node->data; const gint allocated_num = *node_data; if (allocated_num == number) { break; } } if (node != NULL) { titles->priv->allocated_numbers = g_list_remove_link (titles->priv->allocated_numbers, node); g_list_free_full (node, g_free); } } /** * gfls_unsaved_document_titles_get_title: * @titles: a #GflsUnsavedDocumentTitles. * @number: a number. * * Generates the title of an unsaved document. To customize the returned string, * you can use gfls_unsaved_document_titles_set_title_callback(). * * Returns: (transfer full): a suitable title for the unsaved document with the * given @number. * Since: 0.1 */ gchar * gfls_unsaved_document_titles_get_title (GflsUnsavedDocumentTitles *titles, gint number) { g_return_val_if_fail (GFLS_IS_UNSAVED_DOCUMENT_TITLES (titles), NULL); return titles->priv->title_callback (number); } /** * gfls_unsaved_document_titles_set_title_callback: (skip) * @titles: a #GflsUnsavedDocumentTitles. * @title_callback: (nullable): a #GflsUnsavedDocumentTitleCallback. * * Sets a #GflsUnsavedDocumentTitleCallback function. To reset to the default * setting, pass %NULL to @title_callback. * * The callback will be used by gfls_unsaved_document_titles_get_title(). * * Examples: * - "Unsaved Document N" * - "Unsaved File N" * - "Untitled Document N" * - "New Document N" * - Etc. * * Since: 0.1 */ void gfls_unsaved_document_titles_set_title_callback (GflsUnsavedDocumentTitles *titles, GflsUnsavedDocumentTitleCallback title_callback) { g_return_if_fail (GFLS_IS_UNSAVED_DOCUMENT_TITLES (titles)); if (title_callback != NULL) { titles->priv->title_callback = title_callback; } else { titles->priv->title_callback = default_title_cb; } } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-unsaved-document-titles.h000066400000000000000000000056041526404376200303750ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_UNSAVED_DOCUMENT_TITLES_H #define GFLS_UNSAVED_DOCUMENT_TITLES_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS #define GFLS_TYPE_UNSAVED_DOCUMENT_TITLES (gfls_unsaved_document_titles_get_type ()) #define GFLS_UNSAVED_DOCUMENT_TITLES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GFLS_TYPE_UNSAVED_DOCUMENT_TITLES, GflsUnsavedDocumentTitles)) #define GFLS_UNSAVED_DOCUMENT_TITLES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GFLS_TYPE_UNSAVED_DOCUMENT_TITLES, GflsUnsavedDocumentTitlesClass)) #define GFLS_IS_UNSAVED_DOCUMENT_TITLES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GFLS_TYPE_UNSAVED_DOCUMENT_TITLES)) #define GFLS_IS_UNSAVED_DOCUMENT_TITLES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GFLS_TYPE_UNSAVED_DOCUMENT_TITLES)) #define GFLS_UNSAVED_DOCUMENT_TITLES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GFLS_TYPE_UNSAVED_DOCUMENT_TITLES, GflsUnsavedDocumentTitlesClass)) typedef struct _GflsUnsavedDocumentTitles GflsUnsavedDocumentTitles; typedef struct _GflsUnsavedDocumentTitlesClass GflsUnsavedDocumentTitlesClass; typedef struct _GflsUnsavedDocumentTitlesPrivate GflsUnsavedDocumentTitlesPrivate; struct _GflsUnsavedDocumentTitles { GObject parent; GflsUnsavedDocumentTitlesPrivate *priv; }; struct _GflsUnsavedDocumentTitlesClass { GObjectClass parent_class; gpointer padding[12]; }; /** * GflsUnsavedDocumentTitleCallback: * @num: the number. * * Type definition for a function that will be called to create a string * containing @num, to give a name to a document not yet present on disk. * * Returns: (transfer full): the created title. * Since: 0.1 */ typedef gchar *(*GflsUnsavedDocumentTitleCallback) (gint num); G_MODULE_EXPORT GType gfls_unsaved_document_titles_get_type (void); G_MODULE_EXPORT GflsUnsavedDocumentTitles * gfls_unsaved_document_titles_new (void); G_MODULE_EXPORT GflsUnsavedDocumentTitles * gfls_unsaved_document_titles_get_default (void); G_MODULE_EXPORT gint gfls_unsaved_document_titles_allocate_number (GflsUnsavedDocumentTitles *titles); G_MODULE_EXPORT void gfls_unsaved_document_titles_release_number (GflsUnsavedDocumentTitles *titles, gint number); G_MODULE_EXPORT gchar * gfls_unsaved_document_titles_get_title (GflsUnsavedDocumentTitles *titles, gint number); G_MODULE_EXPORT void gfls_unsaved_document_titles_set_title_callback (GflsUnsavedDocumentTitles *titles, GflsUnsavedDocumentTitleCallback title_callback); G_GNUC_INTERNAL void _gfls_unsaved_document_titles_unref_default_instance (void); G_END_DECLS #endif /* GFLS_UNSAVED_DOCUMENT_TITLES_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-utf8-auto-converter.c000066400000000000000000000063131526404376200274440ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-utf8-auto-converter.h" #include "gfls-encoding.h" /** * SECTION:gfls-utf8-auto-converter * @Title: GflsUtf8AutoConverter * @Short_description: Encoding auto-detection and conversion to UTF-8 * * Work-in-progress. */ struct _GflsUtf8AutoConverter { GBytes *input_bytes; GSList *candidate_encodings; guint allow_invalid_bytes : 1; }; /** * gfls_utf8_auto_converter_new: (skip) * @input_bytes: the input data. * @candidate_encodings: (element-type GflsEncoding): a list of #GflsEncoding's. * @allow_invalid_bytes: whether to allow invalid bytes during the conversion. * * Returns: (transfer full): a new #GflsUtf8AutoConverter. * Since: 0.5 */ GflsUtf8AutoConverter * gfls_utf8_auto_converter_new (GBytes *input_bytes, GSList *candidate_encodings, gboolean allow_invalid_bytes) { GflsUtf8AutoConverter *auto_converter; g_return_val_if_fail (input_bytes != NULL, NULL); auto_converter = g_new0 (GflsUtf8AutoConverter, 1); auto_converter->input_bytes = g_bytes_ref (input_bytes); auto_converter->candidate_encodings = g_slist_copy_deep (candidate_encodings, gfls_encoding_copy_func, NULL); auto_converter->allow_invalid_bytes = allow_invalid_bytes != FALSE; return auto_converter; } /** * gfls_utf8_auto_converter_free: * @auto_converter: (nullable): a #GflsUtf8AutoConverter. * * Frees @auto_converter. * * Since: 0.5 */ void gfls_utf8_auto_converter_free (GflsUtf8AutoConverter *auto_converter) { if (auto_converter == NULL) { return; } g_bytes_unref (auto_converter->input_bytes); g_slist_free_full (auto_converter->candidate_encodings, (GDestroyNotify) gfls_encoding_free); g_free (auto_converter); } /** * gfls_utf8_auto_converter_get_validated_string: * @auto_converter: a #GflsUtf8AutoConverter. * * Returns the converted data. * * %NULL can be returned if invalid bytes are disallowed. * * Returns: (transfer none) (nullable): the converted data. * Since: 0.5 */ GflsValidatedString * gfls_utf8_auto_converter_get_validated_string (GflsUtf8AutoConverter *auto_converter) { g_return_val_if_fail (auto_converter != NULL, NULL); /* TODO */ return NULL; } /** * gfls_utf8_auto_converter_get_chosen_encoding: * @auto_converter: a #GflsUtf8AutoConverter. * * Returns the auto-detected #GflsEncoding. * * %NULL can be returned if invalid bytes are disallowed. * * Returns: (transfer none) (nullable): the auto-detected #GflsEncoding. * Since: 0.5 */ const GflsEncoding * gfls_utf8_auto_converter_get_chosen_encoding (GflsUtf8AutoConverter *auto_converter) { g_return_val_if_fail (auto_converter != NULL, NULL); /* TODO */ return NULL; } /** * gfls_utf8_auto_converter_get_lossy_conversion: * @auto_converter: a #GflsUtf8AutoConverter. * * Returns whether the conversion was lossy for the result as returned by * gfls_utf8_auto_converter_get_validated_string(). * * Returns: whether %GFLS_ICONV_RESULT_LOSSY_CONVERSION was encountered. * Since: 0.5 */ gboolean gfls_utf8_auto_converter_get_lossy_conversion (GflsUtf8AutoConverter *auto_converter) { g_return_val_if_fail (auto_converter != NULL, FALSE); /* TODO */ return FALSE; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-utf8-auto-converter.h000066400000000000000000000020211526404376200274410ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS typedef struct _GflsUtf8AutoConverter GflsUtf8AutoConverter; G_MODULE_EXPORT GflsUtf8AutoConverter * gfls_utf8_auto_converter_new (GBytes *input_bytes, GSList *candidate_encodings, gboolean allow_invalid_bytes); G_MODULE_EXPORT void gfls_utf8_auto_converter_free (GflsUtf8AutoConverter *auto_converter); G_MODULE_EXPORT GflsValidatedString * gfls_utf8_auto_converter_get_validated_string (GflsUtf8AutoConverter *auto_converter); G_MODULE_EXPORT const GflsEncoding * gfls_utf8_auto_converter_get_chosen_encoding (GflsUtf8AutoConverter *auto_converter); G_MODULE_EXPORT gboolean gfls_utf8_auto_converter_get_lossy_conversion (GflsUtf8AutoConverter *auto_converter); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-utf8.c000066400000000000000000000112771526404376200244760ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-utf8.h" #include "gfls-utils.h" #include "gfls-validated-string-builder.h" /** * SECTION:gfls-utf8 * @Title: GflsUtf8 * @Short_description: Functions for UTF-8 strings * * Additional functions for UTF-8 strings, to complement what is provided by * GLib. */ /** * gfls_utf8_find_very_long_line: * @str: a UTF-8 nul-terminated string. * @max_n_bytes_per_line: the maximum number of bytes per line, without counting * the newline character(s). * * Finds if a line in @str exceeds @max_n_bytes_per_line. * * For performance reasons, @str is not checked whether it is a valid UTF-8 * string. So you must call for example g_utf8_validate() beforehand. * * Returns: a pointer to the beginning of the first very long line found, or * %NULL if not found. * Since: 0.3 */ const gchar * gfls_utf8_find_very_long_line (const gchar *str, guint max_n_bytes_per_line) { guint cur_pos; guint line_length = 0; g_return_val_if_fail (str != NULL, NULL); for (cur_pos = 0; str[cur_pos] != '\0'; cur_pos++) { gchar ch = str[cur_pos]; if (ch == '\n' || ch == '\r') { line_length = 0; } else { line_length++; if (line_length > max_n_bytes_per_line) { guint line_start_pos = cur_pos - line_length + 1; return str + line_start_pos; } } } return NULL; } /** * gfls_utf8_validate: (skip) * @bytes: a nul-terminated #GBytes. * * Validates @bytes. The invalid bytes will be escaped with * gfls_utils_bytes_to_hex_representation() and will be located in separate * (invalid) #GflsValidatedStringChunk's. * * The format of the input @bytes is important: the data contained in @bytes * must always be nul-terminated, but this must not be included in the #GBytes * length. (The reason is to accommodate the convention of * #GflsValidatedStringChunk, to avoid a copy if the whole @bytes is valid). * * The returned #GflsValidatedString has already been simplified; see * gfls_validated_string_builder_simplify(). * * Returns: (transfer full) (nullable): a new #GflsValidatedString, or %NULL if * @bytes is empty. * Since: 0.5 */ GflsValidatedString * gfls_utf8_validate (GBytes *bytes) { GflsValidatedStringBuilder *builder; const gchar *str_current_position; gsize n_bytes_left = 0; gsize total_n_bytes; g_return_val_if_fail (bytes != NULL, NULL); builder = gfls_validated_string_builder_new (); str_current_position = g_bytes_get_data (bytes, &n_bytes_left); total_n_bytes = n_bytes_left; while (n_bytes_left > 0) { const gchar *str_end_position = NULL; gsize n_valid_bytes; g_utf8_validate_len (str_current_position, n_bytes_left, &str_end_position); n_valid_bytes = str_end_position - str_current_position; /* Fast track, when everything is valid */ if (n_valid_bytes == total_n_bytes) { GflsValidatedStringChunk *valid_chunk; valid_chunk = gfls_validated_string_chunk_new (bytes); gfls_validated_string_chunk_set_valid (valid_chunk, TRUE); gfls_validated_string_builder_append_chunk (builder, valid_chunk); gfls_validated_string_chunk_unref (valid_chunk); break; } /* Create a valid chunk */ if (n_valid_bytes != 0) { gchar *valid_sub_str; GBytes *valid_bytes; GflsValidatedStringChunk *valid_chunk; valid_sub_str = g_malloc (n_valid_bytes + 1); memcpy (valid_sub_str, str_current_position, n_valid_bytes); valid_sub_str[n_valid_bytes] = '\0'; valid_bytes = g_bytes_new_take (valid_sub_str, n_valid_bytes); valid_chunk = gfls_validated_string_chunk_new (valid_bytes); g_bytes_unref (valid_bytes); gfls_validated_string_chunk_set_valid (valid_chunk, TRUE); gfls_validated_string_builder_append_chunk (builder, valid_chunk); gfls_validated_string_chunk_unref (valid_chunk); n_bytes_left -= n_valid_bytes; str_current_position = str_end_position; } /* Create an invalid chunk */ else { gchar *invalid_sub_str; GBytes *invalid_bytes; GflsValidatedStringChunk *invalid_chunk; invalid_sub_str = gfls_utils_bytes_to_hex_representation ((const guint8 *) str_current_position, 1); invalid_bytes = g_bytes_new_take (invalid_sub_str, strlen (invalid_sub_str)); invalid_chunk = gfls_validated_string_chunk_new (invalid_bytes); g_bytes_unref (invalid_bytes); gfls_validated_string_chunk_set_valid (invalid_chunk, FALSE); gfls_validated_string_builder_append_chunk (builder, invalid_chunk); gfls_validated_string_chunk_unref (invalid_chunk); n_bytes_left--; str_current_position++; } } gfls_validated_string_builder_simplify (builder); return gfls_validated_string_builder_free_to_validated_string (builder); } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-utf8.h000066400000000000000000000010661526404376200244760ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_UTF8_H #define GFLS_UTF8_H #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS G_MODULE_EXPORT const gchar * gfls_utf8_find_very_long_line (const gchar *str, guint max_n_bytes_per_line); G_MODULE_EXPORT GflsValidatedString * gfls_utf8_validate (GBytes *bytes); G_END_DECLS #endif /* GFLS_UTF8_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-utils.c000066400000000000000000000040601526404376200247400ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-utils.h" /** * SECTION:gfls-utils * @Title: GflsUtils * @Short_description: Utility functions * * Utility functions. */ /** * gfls_utils_bytes_to_hex_representation: * @bytes: the bytes. * @n_bytes: the number of bytes. * * Returns an ASCII string with each byte taking three characters: backslash * followed by the two hex digits. * * A use-case is for inserting invalid characters into a GTK widget or anything * else that accepts only valid UTF-8 strings. * * Returns: (transfer full): an hexadecimal string representation of @bytes. The * string is nul-terminated. * Since: 0.5 */ gchar * gfls_utils_bytes_to_hex_representation (const guint8 *bytes, gsize n_bytes) { gchar *str; gchar *str_pos; gsize byte_num; g_return_val_if_fail (bytes != NULL, NULL); /* +1 for nul-terminating the string. */ str = g_malloc (n_bytes * 3 + 1); str_pos = str; for (byte_num = 0; byte_num < n_bytes; byte_num++) { guint8 cur_value = bytes[byte_num]; const gchar hex[] = "0123456789ABCDEF"; str_pos[0] = '\\'; str_pos[1] = hex[(cur_value & 0xf0) >> 4]; str_pos[2] = hex[(cur_value & 0x0f) >> 0]; str_pos += 3; } str_pos[0] = '\0'; return str; } /** * gfls_utils_find_nearest_power_of_two: * @number: a number. * * One use-case is for memory (re-)allocations. * * Returns: the smallest power of 2 greater than or equal to @number, or 0 if * such power does not fit in a gsize. * Since: 0.5 */ gsize gfls_utils_find_nearest_power_of_two (gsize number) { /* Note that GLib has a private function doing the same thing, and which * is better optimized, but which uses private stuff and which is more * tricky to understand: g_nearest_pow() from gutilsprivate.h. */ gsize power_of_two = 1; while (power_of_two < number) { /* Do an addition, not a multiplication. Probably faster. */ if (!g_size_checked_add (&power_of_two, power_of_two, power_of_two)) { return 0; } } return power_of_two; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-utils.h000066400000000000000000000007441526404376200247520ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS G_MODULE_EXPORT gchar * gfls_utils_bytes_to_hex_representation (const guint8 *bytes, gsize n_bytes); G_MODULE_EXPORT gsize gfls_utils_find_nearest_power_of_two (gsize number); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-validated-string-builder.c000066400000000000000000000152141526404376200304700ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-validated-string-builder.h" #include "gfls-byte-array.h" /** * SECTION:gfls-validated-string-builder * @Title: GflsValidatedStringBuilder * @Short_description: Builds #GflsValidatedString objects * * Builds #GflsValidatedString objects. */ struct _GflsValidatedStringBuilder { /* (nullable) (element-type GflsValidatedStringChunk) (owned full) */ GPtrArray *chunks; }; static GPtrArray * create_chunks_ptr_array (void) { return g_ptr_array_new_null_terminated (0, (GDestroyNotify) gfls_validated_string_chunk_unref, TRUE); } /** * gfls_validated_string_builder_new: (skip) * * Returns: (transfer full): a new #GflsValidatedStringBuilder. Free with * gfls_validated_string_builder_free_to_validated_string(). * Since: 0.5 */ GflsValidatedStringBuilder * gfls_validated_string_builder_new (void) { return g_new0 (GflsValidatedStringBuilder, 1); } /** * gfls_validated_string_builder_free_to_validated_string: (skip) * @builder: (nullable): a #GflsValidatedStringBuilder. * * Transfers the data from @builder into a new immutable #GflsValidatedString, * and frees @builder. * * Returns %NULL if no chunks have been added to @builder. * * Returns: (nullable) (transfer full): a new #GflsValidatedString, or %NULL. * Since: 0.5 */ GflsValidatedString * gfls_validated_string_builder_free_to_validated_string (GflsValidatedStringBuilder *builder) { GflsValidatedString *validated_string = NULL; g_return_val_if_fail (builder != NULL, NULL); if (builder->chunks != NULL) { GflsValidatedStringChunk **chunks; chunks = (GflsValidatedStringChunk **) g_ptr_array_free (builder->chunks, FALSE); validated_string = _gfls_validated_string_new (chunks); } g_free (builder); return validated_string; } /** * gfls_validated_string_builder_free: * @builder: (nullable): a #GflsValidatedStringBuilder. * * Frees @builder. * * Call this function if you don't need the resulting #GflsValidatedString. * * Since: 0.5 */ void gfls_validated_string_builder_free (GflsValidatedStringBuilder *builder) { GflsValidatedString *validated_string; validated_string = gfls_validated_string_builder_free_to_validated_string (builder); g_object_unref (validated_string); } /** * gfls_validated_string_builder_append_chunk: * @builder: a #GflsValidatedStringBuilder. * @chunk: a #GflsValidatedStringChunk. * * Adds @chunk to the end of the string. * * Since: 0.5 */ void gfls_validated_string_builder_append_chunk (GflsValidatedStringBuilder *builder, GflsValidatedStringChunk *chunk) { g_return_if_fail (builder != NULL); g_return_if_fail (chunk != NULL); if (builder->chunks == NULL) { builder->chunks = create_chunks_ptr_array (); } g_ptr_array_add (builder->chunks, gfls_validated_string_chunk_ref (chunk)); } /** * gfls_validated_string_builder_append_validated_string: * @builder: a #GflsValidatedStringBuilder. * @validated_string: a #GflsValidatedString. * * Adds all the chunks of @validated_string to the end of the string. * * Since: 0.5 */ void gfls_validated_string_builder_append_validated_string (GflsValidatedStringBuilder *builder, GflsValidatedString *validated_string) { GflsValidatedStringChunk **chunks; gint i; g_return_if_fail (builder != NULL); g_return_if_fail (validated_string != NULL); chunks = gfls_validated_string_get_chunks (validated_string); if (chunks == NULL) { return; } for (i = 0; chunks[i] != NULL; i++) { GflsValidatedStringChunk *cur_chunk = chunks[i]; gfls_validated_string_builder_append_chunk (builder, cur_chunk); } } static void byte_array_append_chunk_data (GflsByteArray *byte_array, GflsValidatedStringChunk *chunk) { GBytes *bytes; bytes = gfls_validated_string_chunk_get_bytes (chunk); gfls_byte_array_append (byte_array, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)); } static gboolean chunks_can_be_merged (GflsValidatedStringChunk *chunk1, GflsValidatedStringChunk *chunk2) { gboolean chunk1_is_valid = gfls_validated_string_chunk_get_valid (chunk1) != FALSE; gboolean chunk2_is_valid = gfls_validated_string_chunk_get_valid (chunk2) != FALSE; return (chunk1_is_valid == chunk2_is_valid); } /** * gfls_validated_string_builder_simplify: * @builder: a #GflsValidatedStringBuilder. * * Merges contiguous chunks of the same kind. * * Since: 0.5 */ void gfls_validated_string_builder_simplify (GflsValidatedStringBuilder *builder) { GPtrArray *new_chunks; GflsByteArray *byte_array = NULL; guint current_chunk_num; g_return_if_fail (builder != NULL); if (builder->chunks == NULL) { return; } new_chunks = create_chunks_ptr_array (); for (current_chunk_num = 0; current_chunk_num < builder->chunks->len; current_chunk_num++) { /* At each iteration, consume the current chunk, and peek at the * next chunk to know what to do. At the last iteration, the * next chunk is NULL. */ GflsValidatedStringChunk *current_chunk_from_old_array; guint next_chunk_num = current_chunk_num + 1; GflsValidatedStringChunk *next_chunk_from_old_array = NULL; current_chunk_from_old_array = g_ptr_array_index (builder->chunks, current_chunk_num); if (next_chunk_num < builder->chunks->len) { next_chunk_from_old_array = g_ptr_array_index (builder->chunks, next_chunk_num); } if (next_chunk_from_old_array != NULL && chunks_can_be_merged (current_chunk_from_old_array, next_chunk_from_old_array)) { if (byte_array == NULL) { /* If we are here, it means that: * @current_chunk_from_old_array is the _first_ * chunk to merge in this series. */ byte_array = gfls_byte_array_new (); } byte_array_append_chunk_data (byte_array, current_chunk_from_old_array); } else if (byte_array != NULL) { /* If we are here, it means that: * @current_chunk_from_old_array is the _last_ chunk to * merge in this series. */ GBytes *bytes; byte_array_append_chunk_data (byte_array, current_chunk_from_old_array); bytes = gfls_byte_array_free_to_bytes (byte_array); byte_array = NULL; if (bytes != NULL) { GflsValidatedStringChunk *new_chunk; gboolean valid; new_chunk = gfls_validated_string_chunk_new (bytes); g_bytes_unref (bytes); valid = gfls_validated_string_chunk_get_valid (current_chunk_from_old_array); gfls_validated_string_chunk_set_valid (new_chunk, valid); g_ptr_array_add (new_chunks, new_chunk); } } else { g_ptr_array_add (new_chunks, gfls_validated_string_chunk_ref (current_chunk_from_old_array)); } } g_ptr_array_unref (builder->chunks); builder->chunks = new_chunks; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-validated-string-builder.h000066400000000000000000000021641526404376200304750ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS typedef struct _GflsValidatedStringBuilder GflsValidatedStringBuilder; G_MODULE_EXPORT GflsValidatedStringBuilder * gfls_validated_string_builder_new (void); G_MODULE_EXPORT GflsValidatedString * gfls_validated_string_builder_free_to_validated_string (GflsValidatedStringBuilder *builder); G_MODULE_EXPORT void gfls_validated_string_builder_free (GflsValidatedStringBuilder *builder); G_MODULE_EXPORT void gfls_validated_string_builder_append_chunk (GflsValidatedStringBuilder *builder, GflsValidatedStringChunk *chunk); G_MODULE_EXPORT void gfls_validated_string_builder_append_validated_string (GflsValidatedStringBuilder *builder, GflsValidatedString *validated_string); G_MODULE_EXPORT void gfls_validated_string_builder_simplify (GflsValidatedStringBuilder *builder); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-validated-string-chunk.c000066400000000000000000000103371526404376200301530ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-validated-string-chunk.h" /** * SECTION:gfls-validated-string-chunk * @Title: GflsValidatedStringChunk * @Short_description: A chunk of a #GflsValidatedString * * A chunk of a #GflsValidatedString. */ /* API design: * * Immutability (possible task): * - Add sealing? * - Or put the setters in a separate GflsValidatedStringChunkBuilder class? * - Distinguish between const and non-const pointers to Chunk? * * To extend it: add more public functions here. * * For *external* extensibility: * - Either do it by composition (create a new semi-OOP class with a getter for * the "base class"). * - Or do an heavier OOP design with GObjects, maybe using a design pattern (an * Abstract Factory may be useful, because there is a family of related * (sub-)classes to create). */ struct _GflsValidatedStringChunk { /* Never NULL. */ GBytes *bytes; grefcount ref_count; guint valid : 1; }; G_DEFINE_BOXED_TYPE (GflsValidatedStringChunk, gfls_validated_string_chunk, gfls_validated_string_chunk_ref, gfls_validated_string_chunk_unref) /** * gfls_validated_string_chunk_new: * @bytes: the chunk data. * * Creates a new chunk. * * The format of @bytes is important: the data contained in @bytes must always * be nul-terminated, but this must not be included in the #GBytes length. * * Returns: (transfer full): a new #GflsValidatedStringChunk with a reference * count of one. * Since: 0.5 */ GflsValidatedStringChunk * gfls_validated_string_chunk_new (GBytes *bytes) { GflsValidatedStringChunk *chunk; g_return_val_if_fail (bytes != NULL, NULL); chunk = g_new0 (GflsValidatedStringChunk, 1); chunk->bytes = g_bytes_ref (bytes); g_ref_count_init (&chunk->ref_count); return chunk; } /** * gfls_validated_string_chunk_ref: * @chunk: a #GflsValidatedStringChunk. * * Increases the reference count of @chunk by one. * * Returns: (transfer full): the passed in @chunk. * Since: 0.5 */ GflsValidatedStringChunk * gfls_validated_string_chunk_ref (GflsValidatedStringChunk *chunk) { g_return_val_if_fail (chunk != NULL, NULL); g_ref_count_inc (&chunk->ref_count); return chunk; } /** * gfls_validated_string_chunk_unref: * @chunk: (nullable): a #GflsValidatedStringChunk. * * Decreases the reference count of @chunk by one. If the reference count drops * to 0, @chunk is freed. * * Since: 0.5 */ void gfls_validated_string_chunk_unref (GflsValidatedStringChunk *chunk) { if (chunk == NULL) { return; } if (g_ref_count_dec (&chunk->ref_count)) { g_bytes_unref (chunk->bytes); g_free (chunk); } } /** * gfls_validated_string_chunk_get_bytes: * @chunk: a #GflsValidatedStringChunk. * * The data contained in the #GBytes is always nul-terminated, but this is not * included in the #GBytes length. * * Returns: (transfer none): the @chunk data. * Since: 0.5 */ GBytes * gfls_validated_string_chunk_get_bytes (GflsValidatedStringChunk *chunk) { g_return_val_if_fail (chunk != NULL, NULL); return chunk->bytes; } /** * gfls_validated_string_chunk_get_valid: * @chunk: a #GflsValidatedStringChunk. * * Semantics: * - If the chunk data is “valid”, it means that all the characters in it were * and are valid. * - If the chunk data is “invalid”, it means that all the characters in it were * initially invalid, but have been validated (e.g., by escaping them). * * So, a chunk is either all valid, or all invalid. There can't be a mix of * both. To mix both valid and invalid characters in a string, you need to * create several chunks. * * Returns: whether @chunk contains valid data. * Since: 0.5 */ gboolean gfls_validated_string_chunk_get_valid (GflsValidatedStringChunk *chunk) { g_return_val_if_fail (chunk != NULL, FALSE); return chunk->valid; } /** * gfls_validated_string_chunk_set_valid: * @chunk: a #GflsValidatedStringChunk. * @valid: the value. * * See gfls_validated_string_chunk_get_valid() for the semantics of the @valid * value. * * Since: 0.5 */ void gfls_validated_string_chunk_set_valid (GflsValidatedStringChunk *chunk, gboolean valid) { g_return_if_fail (chunk != NULL); chunk->valid = valid != FALSE; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-validated-string-chunk.h000066400000000000000000000022431526404376200301550ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include #include G_BEGIN_DECLS #define GFLS_TYPE_VALIDATED_STRING_CHUNK (gfls_validated_string_chunk_get_type ()) typedef struct _GflsValidatedStringChunk GflsValidatedStringChunk; G_MODULE_EXPORT GType gfls_validated_string_chunk_get_type (void); G_MODULE_EXPORT GflsValidatedStringChunk * gfls_validated_string_chunk_new (GBytes *bytes); G_MODULE_EXPORT GflsValidatedStringChunk * gfls_validated_string_chunk_ref (GflsValidatedStringChunk *chunk); G_MODULE_EXPORT void gfls_validated_string_chunk_unref (GflsValidatedStringChunk *chunk); G_MODULE_EXPORT GBytes * gfls_validated_string_chunk_get_bytes (GflsValidatedStringChunk *chunk); G_MODULE_EXPORT gboolean gfls_validated_string_chunk_get_valid (GflsValidatedStringChunk *chunk); G_MODULE_EXPORT void gfls_validated_string_chunk_set_valid (GflsValidatedStringChunk *chunk, gboolean valid); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-validated-string.c000066400000000000000000000060161526404376200270440ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "gfls-validated-string.h" /** * SECTION:gfls-validated-string * @Title: GflsValidatedString * @Short_description: A string after a pass of validation * * A string after a pass (or several passes) of validation. * * The use-case for #GflsValidatedString is when you have raw data that must be * validated before being used elsewhere (for example, to insert it into a * #GtkTextBuffer). The initially invalid regions in the data have been made * valid and are marked as such by having separate #GflsValidatedStringChunk's. * See gfls_validated_string_chunk_get_valid(). * * Each chunk is also nul-terminated. */ /* API design: * * Each chunk is nul-terminated because of this requirement for * libgedit-gtksourceview: * * When calling gtk_text_buffer_insert() or a variant of it (with GTK 3 at * least), the UTF-8 string needs to be nul-terminated, for PyGObject * support. To avoid a crash when sending the GtkTextBuffer::insert-text * signal to Python code. * https://gitlab.gnome.org/GNOME/pygobject/-/work_items/68 * "Signal marshalling of string + length (GtkTextBuffer::insert-text)" * * In all cases, it's nicer to have nul-termination. If the GBytes is valid * UTF-8, it can also be treated as a C string. */ struct _GflsValidatedStringPrivate { GflsValidatedStringChunk **chunks; }; G_DEFINE_TYPE_WITH_PRIVATE (GflsValidatedString, gfls_validated_string, G_TYPE_OBJECT) static void gfls_validated_string_finalize (GObject *object) { GflsValidatedString *validated_string = GFLS_VALIDATED_STRING (object); if (validated_string->priv->chunks != NULL) { gint i; for (i = 0; validated_string->priv->chunks[i] != NULL; i++) { GflsValidatedStringChunk *cur_chunk = validated_string->priv->chunks[i]; gfls_validated_string_chunk_unref (cur_chunk); } g_free (validated_string->priv->chunks); } G_OBJECT_CLASS (gfls_validated_string_parent_class)->finalize (object); } static void gfls_validated_string_class_init (GflsValidatedStringClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gfls_validated_string_finalize; } static void gfls_validated_string_init (GflsValidatedString *validated_string) { validated_string->priv = gfls_validated_string_get_instance_private (validated_string); } GflsValidatedString * _gfls_validated_string_new (GflsValidatedStringChunk **chunks) { GflsValidatedString *validated_string; validated_string = g_object_new (GFLS_TYPE_VALIDATED_STRING, NULL); validated_string->priv->chunks = chunks; return validated_string; } /** * gfls_validated_string_get_chunks: * @validated_string: a #GflsValidatedString. * * Returns: (nullable) (transfer none) (array zero-terminated=1): the chunks. * Since: 0.5 */ GflsValidatedStringChunk ** gfls_validated_string_get_chunks (GflsValidatedString *validated_string) { g_return_val_if_fail (GFLS_IS_VALIDATED_STRING (validated_string), NULL); return validated_string->priv->chunks; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls-validated-string.h000066400000000000000000000032161526404376200270500ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #pragma once #if !defined (GFLS_H_INSIDE) && !defined (GFLS_COMPILATION) #error "Only can be included directly." #endif #include G_BEGIN_DECLS #define GFLS_TYPE_VALIDATED_STRING (gfls_validated_string_get_type ()) #define GFLS_VALIDATED_STRING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GFLS_TYPE_VALIDATED_STRING, GflsValidatedString)) #define GFLS_VALIDATED_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GFLS_TYPE_VALIDATED_STRING, GflsValidatedStringClass)) #define GFLS_IS_VALIDATED_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GFLS_TYPE_VALIDATED_STRING)) #define GFLS_IS_VALIDATED_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GFLS_TYPE_VALIDATED_STRING)) #define GFLS_VALIDATED_STRING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GFLS_TYPE_VALIDATED_STRING, GflsValidatedStringClass)) typedef struct _GflsValidatedString GflsValidatedString; typedef struct _GflsValidatedStringClass GflsValidatedStringClass; typedef struct _GflsValidatedStringPrivate GflsValidatedStringPrivate; struct _GflsValidatedString { GObject parent; GflsValidatedStringPrivate *priv; }; struct _GflsValidatedStringClass { GObjectClass parent_class; }; G_MODULE_EXPORT GType gfls_validated_string_get_type (void); G_MODULE_EXPORT GflsValidatedStringChunk ** gfls_validated_string_get_chunks (GflsValidatedString *validated_string); G_GNUC_INTERNAL GflsValidatedString * _gfls_validated_string_new (GflsValidatedStringChunk **chunks); G_END_DECLS libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/gfls.h000066400000000000000000000016651526404376200236170ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef GFLS_H #define GFLS_H #define GFLS_H_INSIDE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef GFLS_H_INSIDE #endif /* GFLS_H */ libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/meson.build000066400000000000000000000067271526404376200246610ustar00rootroot00000000000000gfls_public_headers = [ 'gfls.h', 'gfls-attribute-keys.h', 'gfls-byte-array.h', 'gfls-encoding-conversion.h', 'gfls-encoding-converter.h', 'gfls-encoding.h', 'gfls-error.h', 'gfls-iconv.h', 'gfls-init.h', 'gfls-input-stream.h', 'gfls-loader-basic.h', 'gfls-loader-config.h', 'gfls-loader-config-simple.h', 'gfls-unsaved-document-titles.h', 'gfls-utf8-auto-converter.h', 'gfls-utf8.h', 'gfls-utils.h', 'gfls-validated-string-builder.h', 'gfls-validated-string-chunk.h', 'gfls-validated-string.h', ] gfls_public_c_files = [ 'gfls-attribute-keys.c', 'gfls-byte-array.c', 'gfls-encoding.c', 'gfls-encoding-conversion.c', 'gfls-encoding-converter.c', 'gfls-error.c', 'gfls-iconv.c', 'gfls-init.c', 'gfls-input-stream.c', 'gfls-loader-basic.c', 'gfls-loader-config.c', 'gfls-loader-config-simple.c', 'gfls-unsaved-document-titles.c', 'gfls-utf8-auto-converter.c', 'gfls-utf8.c', 'gfls-utils.c', 'gfls-validated-string-builder.c', 'gfls-validated-string.c', 'gfls-validated-string-chunk.c', ] GFLS_PRIVATE_HEADERS = [] headers_install_dir = get_option('includedir') / '@0@-@1@/gfls/'.format(meson.project_name(), GFLS_API_VERSION) install_headers( gfls_public_headers, install_dir: headers_install_dir ) gfls_enum_types = GNOME.mkenums_simple( 'gfls-enum-types', decorator: 'G_MODULE_EXPORT', header_prefix: '#include ', sources: gfls_public_headers, install_header: true, install_dir: headers_install_dir ) gfls_static_lib = static_library( 'libgedit-gfls-static', [gfls_public_headers, gfls_public_c_files, GFLS_PRIVATE_HEADERS, gfls_enum_types], pic: true, # gfls_static_lib is potentially linked in a shared library. include_directories: ROOT_INCLUDE_DIR, dependencies: GFLS_DEPS, c_args: '-DGFLS_COMPILATION' ) # For unit tests, to be able to test private functions. GFLS_STATIC_DEP = declare_dependency( include_directories: ROOT_INCLUDE_DIR, link_with: gfls_static_lib, sources: gfls_enum_types[1], dependencies: GFLS_DEPS ) symbol_map = 'symbol.map' gfls_lib_link_args = c_compiler.get_supported_link_arguments([ '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), symbol_map), ]) gfls_lib = library( 'gedit-gfls-@0@'.format(GFLS_API_VERSION), dependencies: GFLS_DEPS, link_args: gfls_lib_link_args, link_depends: symbol_map, # link_whole is not supported with MSVC, so we use extract_all_objects(). objects: gfls_static_lib.extract_all_objects(recursive: false), soversion: 0, install: true ) GFLS_LIB_DEP = declare_dependency( include_directories: ROOT_INCLUDE_DIR, link_with: gfls_lib, sources: gfls_enum_types[1], dependencies: GFLS_DEPS ) PKG_CONFIG.generate(gfls_lib, filebase: '@0@-@1@'.format(meson.project_name(), GFLS_API_VERSION), name: meson.project_name(), description: 'File loading and saving', subdirs: '@0@-@1@'.format(meson.project_name(), GFLS_API_VERSION), libraries: GFLS_DEPS, ) if get_option('gobject_introspection') GNOME.generate_gir( gfls_lib, export_packages: '@0@-@1@'.format(meson.project_name(), GFLS_API_VERSION), header: 'gfls/gfls.h', identifier_prefix: 'Gfls', include_directories: ROOT_INCLUDE_DIR, includes: ['Gtk-3.0'], install: true, namespace: 'Gfls', nsversion: GFLS_API_VERSION, sources: [ gfls_public_headers, gfls_public_c_files, gfls_enum_types, ], # Support for deps being built as subprojects: dependencies: GFLS_DEPS, ) endif libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/gfls/symbol.map000066400000000000000000000000431526404376200245040ustar00rootroot00000000000000{ global: gfls_*; local: *; }; libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/libgedit-gfls.doap000066400000000000000000000021031526404376200251250ustar00rootroot00000000000000 libgedit-gfls Gedit Technology - File loading and saving libgedit-gfls is part of Gedit Technology. It is a module dedicated to file loading and saving for the needs of gedit and other similar text editors. C Sébastien Wilmet swilmet libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/meson.build000066400000000000000000000063421526404376200237170ustar00rootroot00000000000000# Convention: # - Local variables in lower_case. # - Global variables in UPPER_CASE. # See: https://github.com/mesonbuild/meson/issues/2607 project( 'libgedit-gfls', 'c', meson_version: '>= 0.64', version: '0.5.0', default_options: ['warning_level=2'] ) GNOME = import('gnome') PKG_CONFIG = import('pkgconfig') I18N = import('i18n') FS = import('fs') # API version, used for parallel installability. GFLS_API_VERSION = '1' GFLS_DEPS = [ dependency('gio-2.0', version: '>= 2.78'), ] GTK3_DEP = dependency('gtk+-3.0', version: '>= 3.22', required: false) # gfls-config.h config_data = configuration_data() GETTEXT_PACKAGE_NAME = '@0@-@1@'.format(meson.project_name(), GFLS_API_VERSION) config_data.set_quoted('GETTEXT_PACKAGE', GETTEXT_PACKAGE_NAME) config_data.set_quoted('GFLS_LOCALEDIR', get_option('prefix') / get_option('localedir')) configure_file( output: 'gfls-config.h', configuration: config_data ) # Misc ROOT_INCLUDE_DIR = include_directories('.') add_project_arguments( '-DG_LOG_DOMAIN="@0@"'.format(meson.project_name()), language: 'c' ) ##### # CFLAGS # Some flags are missing when using only the builtin warning_level meson option, # even at the maximum level. # The following warning_cflags suppose that warning_level=2. c_compiler = meson.get_compiler('c') warning_cflags = [] if c_compiler.get_id() == 'msvc' # Use GLib's msvc_recommended_pragmas.h to filter out # the warnings we don't really need to worry about, # but do make the ones we want to be wary stand out warning_cflags += [ '-FImsvc_recommended_pragmas.h', ] else # Try to mimic the AX_COMPILER_FLAGS Autotools macro. warning_cflags += [ '-fno-strict-aliasing', '-Wundef', '-Wnested-externs', '-Wwrite-strings', '-Wpointer-arith', '-Wmissing-declarations', '-Wmissing-prototypes', '-Wstrict-prototypes', '-Wredundant-decls', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wdeclaration-after-statement', '-Wformat=2', '-Wold-style-definition', '-Wcast-align', '-Wformat-nonliteral', '-Wformat-security', '-Wsign-compare', '-Wstrict-aliasing', '-Wshadow', '-Winline', '-Wpacked', '-Wmissing-format-attribute', '-Wmissing-noreturn', '-Winit-self', '-Wredundant-decls', '-Wmissing-include-dirs', '-Wunused-but-set-variable', '-Warray-bounds', '-Wimplicit-function-declaration', '-Wreturn-type', '-Wswitch-enum', '-Wswitch-default', '-Wduplicated-cond', '-Wduplicated-branches', '-Wlogical-op', '-Wrestrict', '-Wnull-dereference', '-Wjump-misses-init', '-Wdouble-promotion' ] endif supported_warning_cflags = c_compiler.get_supported_arguments(warning_cflags) add_project_arguments(supported_warning_cflags, language: 'c') ##### end CFLAGS subdir('po') subdir('gfls') if get_option('tests') subdir('tests') endif if get_option('gtk_doc') subdir('docs/reference') endif summary('API version', GFLS_API_VERSION) summary('Prefix', get_option('prefix')) summary('GObject Introspection', get_option('gobject_introspection')) summary('API documentation', get_option('gtk_doc')) summary('Build tests', get_option('tests')) summary('Build GTK 3 tests', get_option('tests') and GTK3_DEP.found()) libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/meson_options.txt000066400000000000000000000006051526404376200252060ustar00rootroot00000000000000option( 'gobject_introspection', type: 'boolean', value: true, description: 'Build GObject Introspection data (requires gobject-introspection)' ) option( 'gtk_doc', type: 'boolean', value: true, description: 'Build API reference (requires gtk-doc)' ) option( 'tests', type: 'boolean', value: true, description: 'Build tests (requires gtk3 for interactive GUI tests)' ) libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/000077500000000000000000000000001526404376200221665ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/LINGUAS000066400000000000000000000002301526404376200232060ustar00rootroot00000000000000# Set of available languages. # Please keep this list sorted alphabetically. be bg cs da de el eu hu ka kk kw lt nn pl pt pt_BR ru sl sr sv tr uk zh_CN libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/POTFILES.in000066400000000000000000000010541526404376200237430ustar00rootroot00000000000000# List of source files containing translatable strings. gfls/gfls-attribute-keys.c gfls/gfls-byte-array.c gfls/gfls-encoding.c gfls/gfls-encoding-conversion.c gfls/gfls-encoding-converter.c gfls/gfls-error.c gfls/gfls-iconv.c gfls/gfls-init.c gfls/gfls-input-stream.c gfls/gfls-loader-basic.c gfls/gfls-loader-config.c gfls/gfls-loader-config-simple.c gfls/gfls-unsaved-document-titles.c gfls/gfls-utf8-auto-converter.c gfls/gfls-utf8.c gfls/gfls-utils.c gfls/gfls-validated-string-builder.c gfls/gfls-validated-string.c gfls/gfls-validated-string-chunk.c libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/POTFILES.skip000066400000000000000000000000001526404376200242710ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/be.po000066400000000000000000000154031526404376200231170ustar00rootroot00000000000000# Belarusian translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Yuras Shumovich \n" "Language-Team: Belarusian \n" "Language: be\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Poedit 3.9\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Унікод" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Заходняе" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Цэнтральнаеўрапейскае" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Паўднёваеўрапейскае" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Балтыйскае" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Кірыліца" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Арабскае" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Грэчаскае" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Іўрыт (візуальны)" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Турэцкае" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Скандынаўскае" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Кельцкае" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Румынскае" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Армянскае" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Кітайскае традыцыйнае" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Кірылічнае/Рускае" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Японскае" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Карэйскае" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Кітайскае спрошчанае" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Грузінскае" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Іўрыт" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Кірылічнае/Украінскае" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "В'етнамскае" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Тайскае" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Невядома" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Выканана некалькі незваротных пераўтварэнняў." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Выяўлены недапушчальны сімвал." #: gfls/gfls-encoding-converter.c:158 msgid "No memory available." msgstr "Недастаткова памяці." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Памер файла занадта вялікі." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Дасягнута абмежаванне на колькасць байт для чытання." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Змесціва закадавана не ў UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Змесціва ўтрымлівае занадта доўгі радок." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Пераўтварэнне з кадавання сімвалаў «%s» у «%s» не падтрымліваецца." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "Не ўдалося адкрыць сродак пераўтварэння кадавання сімвалаў з «%s» у «%s»: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Падчас пераўтварэння кадавання сімвалаў узнікла памылка: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Не ўдалося закрыць сродак пераўтварэння кадавання сімвалаў: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Незахаваны дакумент %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/bg.po000066400000000000000000000155451526404376200231300ustar00rootroot00000000000000# Bulgarian translation for libgedit-gfls po-file. # Copyright (C) 2004, 2005, 2006, 2007, 2008,2009, 2010, 2011, 2012, 2013, 2019 Free Software Foundation, Inc. # Copyright (C) 2022, 2025 Alexander Shopov. # Copyright (C) 2025 twlvnn kraftwerk . # This file is distributed under the same license as the libgedit-gfls package. # Vladimir Petkov , 2004. # Alexander Shopov , 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2016, 2022, 2025. # Yavor Doganov , 2008. # twlvnn kraftwerk , 2025. msgid "" msgstr "" "Project-Id-Version: gtksourceview main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/issues\n" "POT-Creation-Date: 2026-08-17 15:23+0000\n" "PO-Revision-Date: 2026-09-10 12:05+0200\n" "Last-Translator: Alexander Shopov \n" "Language-Team: Bulgarian \n" "Language: bg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Уникод" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Западноевропейско" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Централноевропейско" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Южноевропейско" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Балтийско" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Кирилица" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Арабско" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Гръцко" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Визуален иврит" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Турско" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Скандинавско" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Келтско" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Румънско" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Арменско" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Китайско — традиционно" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Кирилица — руска" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Японско" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Корейско" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Китайско — опростено" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Грузинско" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Иврит" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Кирилица — украинска" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Виетнамско" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Тайско" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Непознато" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'WINDOWS-1251', 'UTF-16', 'KOI8-R']" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Извършени са набор от необратими прекодирания." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Срещнат е грешен знак" #: gfls/gfls-encoding-converter.c:158 msgid "No memory available." msgstr "Няма достатъчно памет." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Размерът на файла е прекалено голям." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Достигнато е ограничението на броя байтове за четене." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Съдържанието не е кодирано в UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Съдържанието съдържа много дълъг ред." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Не се поддържа прекодиране от „%s“ към „%s“." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "Модулът за прекодиране от is „%s“ към „%s“ не може да се отвори: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Грешка при прекодиране: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Модулът за прекодиране не може да се затвори: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Незапазен документ %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/cs.po000066400000000000000000000025001526404376200231300ustar00rootroot00000000000000# Czech translation for libgedit-gfls. # Copyright (C) 2025 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Dagobert Janota , 2025. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2025-07-20 08:53+0000\n" "PO-Revision-Date: 2025-07-27 22:02+0200\n" "Last-Translator: Dagobert Janota \n" "Language-Team: Czech\n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Gtranslator 48.0\n" #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Soubor je příliš velký." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Dosažen limit bajtů ke čtení." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Obsah není kódován v UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Soubor obsahuje velmi dlouhý řádek." #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Neuložený dokument %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/da.po000066400000000000000000000041011526404376200231060ustar00rootroot00000000000000# Danish translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Alan Mortensen , 2024-26. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-03-09 14:04+0000\n" "PO-Revision-Date: 2026-03-14 13:21+0100\n" "Last-Translator: Alan Mortensen \n" "Language-Team: Danish \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.4.2\n" #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Filen er for stor." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Grænsen for, hvor mange byte der skal læses, er nået." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Indholdet er ikke kodet i UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Der findes en meget lang linje i indholdet." #: gfls/gfls-iconv.c:138 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Konvertering fra tegnsæt “%s” til “%s” understøttes ikke." #: gfls/gfls-iconv.c:147 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "Kunne ikke åbne et program til konvertering af tegnsæt fra “%s” til “%s”: " "%s" #: gfls/gfls-iconv.c:217 #, c-format msgid "Error during character set conversion: %s" msgstr "Der opstod en fejl under konvertering af tegnsæt: %s" #: gfls/gfls-iconv.c:309 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Kunne ikke lukke programmet til konvertering af tegnsæt: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Dokumentet %d ikke gemt" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/de.po000066400000000000000000000025631526404376200231240ustar00rootroot00000000000000# German translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Jürgen Benvenuti , 2024, 2025. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2025-02-03 13:57+0000\n" "PO-Revision-Date: 2025-02-04 15:19+0100\n" "Last-Translator: Jürgen Benvenuti \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.4.4\n" #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Die Größe der Datei ist zu groß." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Grenze der Anzahl der zu lesenden Bytes wurde erreicht." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Der Inhalt ist nicht in UTF-8 codiert." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Der Inhalt enthält eine sehr lange Zeile." #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Ungespeichertes Dokument %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/el.po000066400000000000000000000030171526404376200231270ustar00rootroot00000000000000# Greek translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Giannis Antypas , 2024. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2024-11-01 18:13+0000\n" "PO-Revision-Date: 2024-11-01 18:13+0000\n" "Last-Translator: Giannis Antypas \n" "Language-Team: Greek \n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: gfls/gfls-loader-basic.c:108 msgid "The file is not encoded in UTF-8." msgstr "Το αρχείο δεν είναι κωδικοποιημένο σε UTF-8." #: gfls/gfls-loader-basic.c:118 msgid "The file contains a very long line." msgstr "Το αρχείο περιέχει μια πολύ μακριά γραμμή." #: gfls/gfls-loader-basic.c:164 msgid "Limit on the number of bytes to read reached." msgstr "Συμπληρώθηκε το όριο στον αριθμό των byte προς ανάγνωση." #: gfls/gfls-loader-basic.c:259 msgid "The size of the file is too big." msgstr "Το μέγεθος του αρχείου είναι πολύ μεγάλο." #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Μη αποθηκευμένο έγγραφο %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/eu.po000066400000000000000000000044311526404376200231410ustar00rootroot00000000000000# Basque translation for libgedit-gfls. # Copyright (C) 2025 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Asier Saratsua Garmendia , 2026. # msgid "" msgstr "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/issues\n" "POT-Creation-Date: 2026-04-25 17:46+0000\n" "PO-Revision-Date: 2026-05-17 20:14+0000\n" "Last-Translator: Asier Saratsua Garmendia \n" "Language-Team: Basque \n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Desegin ezin daitezkeen zenbait bihurketa egin dira." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Karaktere baliogabe bat aurkitu da." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Fitxategiaren tamaina handiegia da." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Irakurri daitekeen byte kopuruaren mugara iritsi da." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Edukia ez dago UTF-8 kodeketan kodetuta." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Edukiak lerro oso luzea du." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Ez da onartzen “%s” karaktere-jokotik “%s” karaktere-jokora bihurtzea." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "Hutz egin du “%s” eta “%s” karaktere-jokoen arteko bihurtzaile bat irekitzeak: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Errorera karaktere-jokoak bihurtzean: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Huts egin du karaktere-jokoen bihurtzailea ixteak: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Gorde gabeko %d dokumentua" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/hu.po000066400000000000000000000140561526404376200231500ustar00rootroot00000000000000# Hungarian translation for libgedit-gfls. # Copyright (C) 2025, 2026 Free Software Foundation, Inc. # This file is distributed under the same license as the libgedit-gfls package. # # Balázs Úr , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/iss" "ues\n" "POT-Creation-Date: 2026-08-17 15:23+0000\n" "PO-Revision-Date: 2026-09-09 20:39+0200\n" "Last-Translator: Balázs Úr \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Lokalize 25.12.3\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unicode" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Nyugati" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Közép-európai" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Dél-európai" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Balti" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Cirill" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Arab" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Görög" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Héber (vizuális)" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Török" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Skandináv" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Kelta" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Román" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Örmény" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Kínai (hagyományos)" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Cirill/orosz" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Japán" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Koreai" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Kínai (egyszerűsített)" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Grúz" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Héber" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Cirill/ukrán" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Vietnámi" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Thai" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Ismeretlen" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-2', 'WINDOWS-1250', 'IBM852', 'UTF-16']" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Számos visszafordíthatatlan átalakítás lett végrehajtva." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Érvénytelen karakter fordult elő." #: gfls/gfls-encoding-converter.c:158 msgid "No memory available." msgstr "Nincs elérhető memória." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "A fájl mérete túl nagy." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "A beolvasandó bájtok számának korlátja elérve." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "A tartalom nem UTF-8 kódolású." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "A tartalom egy nagyon hosszú sort tartalmaz." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "" "A(z) „%s” és a(z) „%s” karakterkészletek közötti átalakítás nem támogatott." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "Nem sikerült megnyitni a(z) „%s” és a(z) „%s” karakterkészletek közötti " "átalakítót: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Hiba a karakterkészlet-átalakítás során: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Nem sikerült bezárni a karakterkészlet-átalakítót: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Mentetlen dokumentum %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/ka.po000066400000000000000000000162131526404376200231240ustar00rootroot00000000000000# Georgian translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's authors # This file is distributed under the same license as the libgedit-gfls package. # Ekaterine Papava , 2024-2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-10-06 23:05+0000\n" "PO-Revision-Date: 2026-10-09 04:46+0200\n" "Last-Translator: Ekaterine Papava \n" "Language-Team: Georgian \n" "Language: ka\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 3.9\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "უნიკოდი" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "დასავლური" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "ცენტრალურ ევროპული" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "სამხრეთ ევროპული" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "ბალტიური" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "კირილიცა" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "არაბული" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "ბერძნული" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "ივრითი ვიზუალი" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "თურქული" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "სკანდინავიური" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "კელტური" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "რუმინული" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "სომხური" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "ჩინური ტრადიციული" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "კირილიცა/რუსული" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "იაპონური" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "კორეული" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "ჩინური გამარტივებული" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "ქართული" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "ივრითი" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "კირილიცა/უკრაინული" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "ვიეტნამური" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "ტაილანდური" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "უცნობი" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-converter.c:308 msgid "An invalid byte has been encountered during character set conversion." msgstr "სიმბოლოების ნაკრების გადაყვანისას აღმოჩენილია არასწორი სიმბოლო." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "ფაილის ზომა ძალიან დიდია." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "შეზღუდეთ ბაიტების რაოდენობა, რომ წაიკითხოთ." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "შემცველობა არ არის კოდირებული UTF-8- ში." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "შემცველობა შეიცავს ძალიან გრძელი ხაზს." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "სიმბოლოების ნაკრებიდან “%s” “%s”-ზე გადაყვანა მხარდაჭერილი არაა." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "სიმბოლოების ნაკრების \"%s\"-დან \"%s\"-ზე გადამყვანის გახსნა ჩავარდა: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "შეცდომა სიმბოლოების ნაკრების გადაყვანისას: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "სიმბოლოების ნაკრების გადამყვანის დახურვა ჩავარდა: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "შეუნახავი დოკუმენტი %d" #, c-format #~ msgid "A number of nonreversible conversions have been performed." #~ msgstr "შესრულებული შეუქცევადი გადაყვანების რაოდენობა." #, c-format #~ msgid "%s (%s)" #~ msgstr "%s (%s)" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/kk.po000066400000000000000000000146711526404376200231440ustar00rootroot00000000000000# Kazakh translation for libgedit-gfls. # Copyright (C) 2026 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Baurzhan Muftakhidinov , 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-08-17 15:23+0000\n" "PO-Revision-Date: 2026-08-22 08:52+0500\n" "Last-Translator: Baurzhan Muftakhidinov \n" "Language-Team: Kazakh \n" "Language: kk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 3.9\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unicode" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Батыс" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Орталық еуропалық" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Оңтүстік еуропалық" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Балтық" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Кириллица" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Араб" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Грек" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Визуалды иврит" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Түрік" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Нордтық" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Кельт" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Румын" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Армян" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Дәстүрлі қытай" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Кириллица/Орыс" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Жапон" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Кәріс" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Жеңілдетілген қытай" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Грузин" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Иврит" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Кириллица/Украин" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Вьетнам" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Тай" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Белгісіз" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Бірнеше қайтарылмайтын түрлендіру жұмыстары жүргізілді." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Жарамсыз таңба кездестірілді." #: gfls/gfls-encoding-converter.c:158 msgid "No memory available." msgstr "Қолжетімді жады жоқ." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Файл өлшемі тым үлкен." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Оқуға болатын байттар санының шегіне жетті." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Мазмұны UTF-8 кодында кодталмаған." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Мазмұнда тым ұзын жол бар." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "«%s» таңбалар жиынынан «%s» жиынына түрлендіруге қолдау көрсетілмейді." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "«%s» жиынынан «%s» жиынына таңбалар жиынын түрлендіргішті ашу сәтсіз " "аяқталды: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Таңбалар жиынын түрлендіру кезіндегі қате: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Таңбалар жиынын түрлендіргішті жабу сәтсіз аяқталды: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Сақталмаған құжат %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/kw.po000066400000000000000000000027761526404376200231630ustar00rootroot00000000000000# Cornish translation for libgedit-gfls. # Copyright (C) 2026 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # FIRST AUTHOR , YEAR. # Flynn Peck , 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2025-02-02 20:05+0000\n" "PO-Revision-Date: 2026-01-28 23:04+0000\n" "Last-Translator: Flynn Peck \n" "Language-Team: kw\n" "Language: kw\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-DL-VCS-Web: https://gitlab.gnome.org/World/gedit/libgedit-gfls\n" "X-DL-Lang: kw\n" "X-DL-Module: libgedit-gfls\n" "X-DL-Branch: main\n" "X-DL-Domain: po\n" "X-DL-State: Translating\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Gtranslator 49.0\n" #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "An braster a'n restren yw re bras." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Finweth war'n niver baytys rag redya hedhys." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "An dalgh na kodennys yn UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "An dalgh kontaynya unn linen pur hir." #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Skrif Ansawys %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/lt.po000066400000000000000000000136511526404376200231530ustar00rootroot00000000000000# Lithuanian translation for libgedit-gfls. # Copyright (C) 2026 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Aurimas Aurimas Černius , 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-10-06 23:05+0000\n" "PO-Revision-Date: 2026-10-12 22:35+0300\n" "Last-Translator: Aurimas Černius \n" "Language-Team: Lithuanian \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "(n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Poedit 3.9\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unikodas" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Vakarietiška" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Centrinės Europos" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Pietų Europos" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Baltijos" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Kirilica" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Arabų" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Graikų" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Hebrajų vaizdinė" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Turkų" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Šiaurės" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Keltų" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Rumunų" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Armėnų" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Kinų tradicinė" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Kirilica/rusų" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Japonų" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Korėjiečių" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Kinų supaprastintą" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Kartvelų" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Hebrajų" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Kirilica/ukrainiečių" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Vietnamiečių" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Tailandiečių" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Nežinoma" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-converter.c:308 msgid "An invalid byte has been encountered during character set conversion." msgstr "Aptiktas netinkamas baitas konvertuojant simbolių koduotę." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Failas yra per didelis." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Pasiekta skaitomų baitų skaičiaus riba." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Turinys nėra koduotas UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Turinyje yra labai ilgai eilutė." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Pakeitimas iš simbolių koduotės „%s“ į „%s“ nepalaikomas." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "Nepavyko atverti simbolių koduotės konverterio iš „%s“ į „%s“: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Klaida konvertuojant simbolius: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Nepavyko užverti simbolių koduotės konverterio: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Neįrašytas dokumentas %d" #, c-format #~ msgid "A number of nonreversible conversions have been performed." #~ msgstr "Įvykdyta daug neatšaukiamų pakeitimų." libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/meson.build000066400000000000000000000000711526404376200243260ustar00rootroot00000000000000I18N.gettext( GETTEXT_PACKAGE_NAME, preset: 'glib' ) libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/nn.po000066400000000000000000000131241526404376200231420ustar00rootroot00000000000000# Norwegian Nynorsk translation for libgedit-gfls. # This file is distributed under the same license as the libgedit-gfls package. # Roy-Magne Mo , 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-10-06 23:05+0000\n" "PO-Revision-Date: 2026-10-09 20:30+0200\n" "Last-Translator: Roy-Magne Mo \n" "Language-Team: Norwegian Nynorsk \n" "Language: nn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unicode" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Vestleg" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Sentraleuropeisk" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Søreuropeisk" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Baltisk" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Kyrillisk" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Arabisk" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Gresk" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Visuell hebraisk" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Tyrkisk" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Nordisk" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Keltisk" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Rumensk" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Armensk" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Tradisjonell kinesisk" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Kyrillisk/russisk" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Japansk" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Koreansk" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Forenkla kinesisk" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Georgisk" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Hebraisk" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Kyrillisk/ukrainsk" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Vietnamesisk" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Thai" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Ukjend" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-converter.c:308 msgid "An invalid byte has been encountered during character set conversion." msgstr "Fann ein ugyldig byte under konverteringa av teiknsettet." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Fila er for stor." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Nådde grensa for kor mange byte som skal lesast." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Innhaldet er ikkje koda i UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Innhaldet inneheld ei svært lang linje." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Konvertering frå teiknsettet «%s» til «%s» er ikkje støtta." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "Klarte ikkje opne ein teiknsettomformar frå «%s» til «%s»: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Feil under konverteringa av teiknsettet: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Klarte ikkje lukke teiknsettomformaren: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Ulagra dokument %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/pl.po000066400000000000000000000026331526404376200231450ustar00rootroot00000000000000# Polish translation for libgedit-gfls. # Copyright © 2025 the libgedit-gfls authors. # This file is distributed under the same license as the libgedit-gfls package. # Piotr Drąg , 2025. # Aviary.pl , 2025. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2025-02-24 17:44+0000\n" "PO-Revision-Date: 2025-03-02 15:18+0100\n" "Last-Translator: Piotr Drąg \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Rozmiar pliku jest za duży." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Osiągnięto ograniczenie liczby bajtów do odczytu." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Treść nie jest zakodowana jako UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Treść zawiera bardzo długi wiersz." #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Niezapisany dokument %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/pt.po000066400000000000000000000137331526404376200231600ustar00rootroot00000000000000# Portuguese translation for libgedit-gfls. # Copyright (C) 2026 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # catias89 , 2026. # Hugo Carvalho , 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-06-15 12:04+0000\n" "PO-Revision-Date: 2026-07-29 10:57+0100\n" "Last-Translator: Hugo Carvalho \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.9\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unicode" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Ocidental" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Europa Central" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Sul da Europa" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Báltico" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Cirílico" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Árabe" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Grego" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Hebraico Visual" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Turco" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Nórdico" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Céltico" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Romeno" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Arménio" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Chinês Tradicional" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Cirílico/Russo" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Japonês" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Coreano" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Chinês Simplificado" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Georgiano" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Hebraico" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Cirílico/Ucraniano" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Vietnamita" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Tailandês" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Desconhecido" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Foram executadas varias conversões irreversíveis." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Foi encontrado um caractere inválido." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "O ficheiro é demasiado grande." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Alcançado o limite do número de bytes para leitura." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "O conteúdo não está codificado em UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "O conteúdo possui uma linha muito longa." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "" "A conversão do conjunto de caracteres \"%s\" para \"%s\" não é suportada." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "Não foi possível abrir um conversor de conjunto de caracteres de \"%s\" para " "\"%s\": %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Ocorreu um erro durante a conversão de um conjunto de caracteres: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Não foi possível fechar o conversor do conjunto de caracteres: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Documento não guardado %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/pt_BR.po000066400000000000000000000142771526404376200235470ustar00rootroot00000000000000# Brazilian Portuguese translation for libgedit-gfls. # Copyright (C) 2025 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Rafael Fontenelle , 2024-2025. # Juliano de Souza Camargo , 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-08-17 15:23+0000\n" "PO-Revision-Date: 2026-09-07 16:27-0300\n" "Last-Translator: Juliano de Souza Camargo \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Gtranslator 50.0\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unicode" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Ocidental" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Centro europeu" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Europa sulista" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Báltico" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Cirílico" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Árabe" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Grego" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Hebraico visual" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Turco" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Nórdico" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Céltico" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Romeno" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Armênio" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Chinês tradicional" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Cirílico/Russo" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Japonês" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Coreano" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Chinês simplificado" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Georgiano" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Hebraico" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Cirílico/Ucraniano" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Vietinamita" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Tailandês" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Desconhecido" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Um número de conversões irreversíveis foi processada." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Um caractere inválido foi encontrado." #: gfls/gfls-encoding-converter.c:158 msgid "No memory available." msgstr "Sem memória disponível." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "O tamanho do arquivo é grande demais." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Foi alcançado o limite de número de bytes para leitura." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "O conteúdo não está codificado em UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "O conteúdo contém uma linha muito longa." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Não há suporte à conversão do conjunto de caracteres “%s” para “%s”" #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "Não foi possível abrir conversor de conjunto de caracteres “%s” para “%s”: " "“%s”" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Erro durante a conversão do conjunto de caracteres: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Não foi possível fechar o conversor de conjunto de caracteres: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Documento não salvo %d" #, c-format #~ msgid "%s (%s)" #~ msgstr "%s (%s)" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/ru.po000066400000000000000000000103371526404376200231600ustar00rootroot00000000000000# Russian translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Sergej A. , 2024. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-03-26 11:38+0000\n" "PO-Revision-Date: 2026-04-04 23:47+1000\n" "Last-Translator: Ser82-png \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Poedit 3.0.1\n" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Количество выполненных необратимых преобразований." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Выявлен недопустимый символ." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Размер файла слишком большой." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Превышено ограничение на количество байт для чтения." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Содержимое этого файла не в кодировке UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Содержимое имеет слишком длинную строку." #: gfls/gfls-iconv.c:138 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Преобразование из кодировки символов «%s» в «%s» не поддерживается." #: gfls/gfls-iconv.c:147 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "Не удалось открыть конвертер кодировки символов из «%s» в «%s»: %s" #: gfls/gfls-iconv.c:217 #, c-format msgid "Error during character set conversion: %s" msgstr "Ошибка при преобразовании кодировки символов: %s" #: gfls/gfls-iconv.c:309 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Не удалось закрыть конвертер кодировки символов: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Несохранённый документ %d" #, c-format #~ msgid "%s (%s)" #~ msgstr "%s (%s)" #~ msgid "Unicode" #~ msgstr "Юникод" #~ msgid "Western" #~ msgstr "Западная" #~ msgid "Central European" #~ msgstr "Центральноевропейская" #~ msgid "South European" #~ msgstr "Южноевропейская" #~ msgid "Baltic" #~ msgstr "Балтийская" #~ msgid "Cyrillic" #~ msgstr "Кириллица" #~ msgid "Arabic" #~ msgstr "Арабская" #~ msgid "Greek" #~ msgstr "Греческая" #~ msgid "Hebrew Visual" #~ msgstr "Еврейская отображаемая" #~ msgid "Turkish" #~ msgstr "Турецкая" #~ msgid "Nordic" #~ msgstr "Северная" #~ msgid "Celtic" #~ msgstr "Кельтская" #~ msgid "Romanian" #~ msgstr "Румынская" #~ msgid "Armenian" #~ msgstr "Армянская" #~ msgid "Chinese Traditional" #~ msgstr "Китайская традиционная" #~ msgid "Cyrillic/Russian" #~ msgstr "Кириллица/Русская" #~ msgid "Japanese" #~ msgstr "Японская" #~ msgid "Korean" #~ msgstr "Корейская" #~ msgid "Chinese Simplified" #~ msgstr "Китайская упрощённая" #~ msgid "Georgian" #~ msgstr "Грузинская" #~ msgid "Hebrew" #~ msgstr "Еврейская" #~ msgid "Cyrillic/Ukrainian" #~ msgstr "Кириллица/Украинская" #~ msgid "Vietnamese" #~ msgstr "Вьетнамская" #~ msgid "Thai" #~ msgstr "Тайская" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/sl.po000066400000000000000000000133251526404376200231500ustar00rootroot00000000000000# Slovenian translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Martin , 2024,2025,2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-10-03 04:56+0000\n" "PO-Revision-Date: 2026-10-03 12:37+0200\n" "Last-Translator: Martin Srebotnjak \n" "Language-Team: Slovenian \n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || " "n%100==4 ? 3 : 0) ;\n" "X-Generator: Poedit 3.8\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unicode" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "zahodna" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "srednjeevropska" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "južnoevropska" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "baltska" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "cirilica" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "arabska" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "grška" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "hebrejska predočena" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "turška" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "nordijska" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "keltska" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "romunska" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "armenska" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "kitajska tradicionalna" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "cirilica/ruska" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "japonska" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "korejska" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "kitajska poenostavljena" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "gruzijska" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "hebrejska" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "cirilica/ukrajinska" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "vietnamska" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "tajska" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "neznana" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'TRENUTNI', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-converter.c:308 msgid "An invalid byte has been encountered during character set conversion." msgstr "Pri pretvorbi nabora znakov je bil zaznan neveljaven bajt." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Datoteka je prevelika." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Dosežena je omejitev števila bajtov za branje." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Vsebina ni kodirana v UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Vsebina vsebuje zelo dolgo vrstico." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Pretvorba iz nabora znakov »%s« v »%s« ni podprta." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "Pretvornika nabora znakov iz »%s« v »%s« ni mogoče odpreti: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Napaka med pretvorbo nabora znakov: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Pretvornika nabora znakov ni bilo mogoče zapreti: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Neshranjeni dokument %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/sr.po000066400000000000000000000077311526404376200231620ustar00rootroot00000000000000# Serbian translation of libgedit-gfls. # This file is distributed under the same license as the libgedit-gfls package. # Мирослав Николић # Марко Костић , 2026. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-03-26 11:38+0000\n" "PO-Revision-Date: 2025-01-26 08:23+0100\n" "Last-Translator: Мирослав Николић \n" "Language-Team: \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 3.5\n" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Извршен је одређени број неповратних претварања." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Наишао сам на неисправан знак." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Датотека је превелика." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Достигнуто је ограничење броја бајтова за читање." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Садржај није кодиран у УТФ-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Садржај садржи врло дуг ред." #: gfls/gfls-iconv.c:138 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Претварање из скупа знакова „%s“ у „%s“ није подржано." #: gfls/gfls-iconv.c:147 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "Нисам успео да отворим претварач скупа знакова из „%s“ у „%s“: %s" #: gfls/gfls-iconv.c:217 #, c-format msgid "Error during character set conversion: %s" msgstr "Грешка приликом претварања скупа знакова: %s" #: gfls/gfls-iconv.c:309 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Нисам успео да затворим претварач скупа знакова: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Несачувани документ %d" #, c-format #~ msgid "%s (%s)" #~ msgstr "%s (%s)" #~ msgid "Unicode" #~ msgstr "Јуникод" #~ msgid "Western" #~ msgstr "Западни" #~ msgid "Central European" #~ msgstr "Средње-европски" #~ msgid "South European" #~ msgstr "Јужно-европски" #~ msgid "Baltic" #~ msgstr "Балтички" #~ msgid "Cyrillic" #~ msgstr "Ћирилица" #~ msgid "Arabic" #~ msgstr "Арапски" #~ msgid "Greek" #~ msgstr "Грчки" #~ msgid "Hebrew Visual" #~ msgstr "Јеврејски визуелни" #~ msgid "Turkish" #~ msgstr "Турски" #~ msgid "Nordic" #~ msgstr "Нордијски" #~ msgid "Celtic" #~ msgstr "Келтски" #~ msgid "Romanian" #~ msgstr "Румунски" #~ msgid "Armenian" #~ msgstr "Јерменски" #~ msgid "Chinese Traditional" #~ msgstr "Кинески традиционални" #~ msgid "Cyrillic/Russian" #~ msgstr "Ћирилица/руски" #~ msgid "Japanese" #~ msgstr "Јапански" #~ msgid "Korean" #~ msgstr "Корејски" #~ msgid "Chinese Simplified" #~ msgstr "Кинески поједностављен" #~ msgid "Georgian" #~ msgstr "Грузијски" #~ msgid "Hebrew" #~ msgstr "Јеврејски" #~ msgid "Cyrillic/Ukrainian" #~ msgstr "Ћирилица/украјински" #~ msgid "Vietnamese" #~ msgstr "Вијетнамски" #~ msgid "Thai" #~ msgstr "Тајландски" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/sv.po000066400000000000000000000140141526404376200231560ustar00rootroot00000000000000# Swedish translation for libgedit-gfls. # Copyright © 2024-2026 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # Anders Jonsson , 2024, 2025, 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-10-03 04:56+0000\n" "PO-Revision-Date: 2026-10-08 23:06+0200\n" "Last-Translator: Anders Jonsson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.9\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Unicode" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "Västerländsk" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "Centraleuropeisk" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "Sydeuropeisk" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "Baltisk" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "Kyrillisk" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "Arabisk" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "Grekisk" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "Hebreisk visuell" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "Turkisk" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "Nordisk" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "Keltisk" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "Rumänsk" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "Armenisk" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "Traditionell kinesisk" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "Kyrillisk/rysk" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "Japansk" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "Koreansk" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "Förenklad kinesisk" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "Georgisk" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "Hebreisk" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "Kyrillisk/ukrainsk" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "Vietnamesisk" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "Thailändsk" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "Okänd" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-converter.c:308 msgid "An invalid byte has been encountered during character set conversion." msgstr "" "En ogiltig byte har påträffats under konvertering av teckenuppsättning." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Filen är för stor." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Gräns för antal byte att läsa uppnådd." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Innehållet är inte kodat i UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Innehållet innehåller en väldigt lång rad." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "Konvertering från teckenuppsättningen ”%s” till ”%s” stöds inte." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "Misslyckades med att öppna en teckenuppsättningskonverterare från ”%s” till " "”%s”: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Fel under konvertering av teckenuppsättning: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Misslyckades med att stänga teckenuppsättningskonverteraren: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Osparat dokument %d" #, c-format #~ msgid "A number of nonreversible conversions have been performed." #~ msgstr "Ett antal irreversibla konverteringar har utförts." #~ msgid "No memory available." #~ msgstr "Inget minne tillgängligt." libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/tr.po000066400000000000000000000046721526404376200231640ustar00rootroot00000000000000# Turkish translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # # Sabri Ünal , 2024, 2026. # Emin Tufan Çetin , 2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-04-25 17:46+0000\n" "PO-Revision-Date: 2026-05-04 08:00+0300\n" "Last-Translator: Emin Tufan Çetin \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 3.9\n" #: gfls/gfls-encoding-convert.c:344 #, c-format msgid "A number of nonreversible conversions have been performed." msgstr "Bir dizi geri dönüşü olmayan dönüşüm gerçekleştirildi." #: gfls/gfls-encoding-convert.c:358 #, c-format msgid "An invalid character has been encountered." msgstr "Geçersiz bir karakterle karşılaşıldı." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Dosyanın boyutu çok büyük." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Okunacak bayt sayısı sınırına ulaşıldı." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "İçerik UTF-8 olarak kodlanmamış." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "İçerik çok uzun bir satır içeriyor." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "" "“%s” karakter kümesinden “%s” karaker kümesine dönüştürme desteklenmiyor." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "“%s” karakter kümesinden “%s” karakter kümesine dönüştürücü açılamadı: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Karakter kümesi dönüştürülürken hata: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Karakter kümesi dönüştürücüsü kapatılamadı: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Kaydedilmemiş Belge %d" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/uk.po000066400000000000000000000157421526404376200231560ustar00rootroot00000000000000# Ukrainian translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # # SPDX-FileCopyrightText: 2024, 2025, 2026 Yuri Chornoivan msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/iss" "ues\n" "POT-Creation-Date: 2026-10-03 13:51+0000\n" "PO-Revision-Date: 2026-10-03 18:52+0300\n" "Last-Translator: Yuri Chornoivan \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%10>=2" " && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Lokalize 25.12.1\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "Юнікод" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "західноєвропейське" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "центральноєвропейське" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "південноєвропейське" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "балтійське" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "кирилиця" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "арабське" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "грецьке" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "іврит (візуальне)" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "турецьке" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "нордичне" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "кельтське" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "румунське" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "вірменське" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "традиційне китайське" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "кирилиця/російське" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "японське" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "корейське" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "спрощене китайське" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "грузинське" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "іврит" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "кирилиця/українське" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "в'єтнамське" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "тайське" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "невідоме" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'CP1251', 'KOI8U', 'UTF-16']" #: gfls/gfls-encoding-converter.c:308 #| msgid "An invalid character has been encountered." msgid "An invalid byte has been encountered during character set conversion." msgstr "" "Під час спроби перетворення кодування символів виявлено некоректний байт." #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "Розмір файла є надто великим." #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "Перевищено обмеження кількості байтів для читання." #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "Дані у цьому файлі не записано у кодуванні UTF-8." #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "Файл містить надто довгий рядок." #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "" "Підтримки перетворення з кодування «%s» на кодування «%s» не передбачено." #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "" "Не вдалося відкрити засіб перетворення кодувань символів з «%s» на «%s»: %s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "Помилка під час перетворення кодувань символів: %s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "Не вдалося закрити засіб перетворення кодувань символів: %s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "Незбережений документ %d" #, c-format #~ msgid "A number of nonreversible conversions have been performed." #~ msgstr "Кількість виконаних незворотних перетворень." #~ msgid "No memory available." #~ msgstr "Немає доступної пам'яті." #, c-format #~ msgid "%s (%s)" #~ msgstr "%s (%s)" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/po/zh_CN.po000066400000000000000000000136221526404376200235330ustar00rootroot00000000000000# Chinese (China) translation for libgedit-gfls. # Copyright (C) 2024 libgedit-gfls's COPYRIGHT HOLDER # This file is distributed under the same license as the libgedit-gfls package. # lumingzh , 2024-2026. # msgid "" msgstr "" "Project-Id-Version: libgedit-gfls main\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/" "issues\n" "POT-Creation-Date: 2026-10-03 13:51+0000\n" "PO-Revision-Date: 2026-10-04 07:39+0800\n" "Last-Translator: lumingzh \n" "Language-Team: Chinese (China) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Gtranslator 51.0\n" #. UTF-8 first, so that it's the first encoding returned by #. * gfls_encoding_get_all(). #. #: gfls/gfls-encoding.c:96 gfls/gfls-encoding.c:113 gfls/gfls-encoding.c:114 #: gfls/gfls-encoding.c:115 gfls/gfls-encoding.c:116 gfls/gfls-encoding.c:117 #: gfls/gfls-encoding.c:118 gfls/gfls-encoding.c:119 msgid "Unicode" msgstr "万国码" #. FIXME GEOSTD8 ? #: gfls/gfls-encoding.c:98 gfls/gfls-encoding.c:110 gfls/gfls-encoding.c:138 #: gfls/gfls-encoding.c:161 msgid "Western" msgstr "西文" #: gfls/gfls-encoding.c:99 gfls/gfls-encoding.c:139 gfls/gfls-encoding.c:159 msgid "Central European" msgstr "中欧" #: gfls/gfls-encoding.c:100 msgid "South European" msgstr "南欧" #: gfls/gfls-encoding.c:101 gfls/gfls-encoding.c:108 gfls/gfls-encoding.c:166 msgid "Baltic" msgstr "波罗的海语" #: gfls/gfls-encoding.c:102 gfls/gfls-encoding.c:140 gfls/gfls-encoding.c:147 #: gfls/gfls-encoding.c:149 gfls/gfls-encoding.c:150 gfls/gfls-encoding.c:160 msgid "Cyrillic" msgstr "西里尔语" #: gfls/gfls-encoding.c:103 gfls/gfls-encoding.c:143 gfls/gfls-encoding.c:165 msgid "Arabic" msgstr "阿拉伯语" #: gfls/gfls-encoding.c:104 gfls/gfls-encoding.c:162 msgid "Greek" msgstr "希腊语" #: gfls/gfls-encoding.c:105 msgid "Hebrew Visual" msgstr "可视希伯来语" #: gfls/gfls-encoding.c:106 gfls/gfls-encoding.c:141 gfls/gfls-encoding.c:163 msgid "Turkish" msgstr "土耳其语" #: gfls/gfls-encoding.c:107 msgid "Nordic" msgstr "北欧" #: gfls/gfls-encoding.c:109 msgid "Celtic" msgstr "凯尔特语" #: gfls/gfls-encoding.c:111 msgid "Romanian" msgstr "罗马尼亚语" #: gfls/gfls-encoding.c:121 msgid "Armenian" msgstr "亚美尼亚语" #: gfls/gfls-encoding.c:122 gfls/gfls-encoding.c:123 gfls/gfls-encoding.c:131 msgid "Chinese Traditional" msgstr "繁体中文" #: gfls/gfls-encoding.c:124 msgid "Cyrillic/Russian" msgstr "西里尔文/俄语" #: gfls/gfls-encoding.c:126 gfls/gfls-encoding.c:127 gfls/gfls-encoding.c:128 #: gfls/gfls-encoding.c:145 gfls/gfls-encoding.c:153 msgid "Japanese" msgstr "日语" #: gfls/gfls-encoding.c:130 gfls/gfls-encoding.c:146 gfls/gfls-encoding.c:148 #: gfls/gfls-encoding.c:156 msgid "Korean" msgstr "朝鲜语" #: gfls/gfls-encoding.c:133 gfls/gfls-encoding.c:134 gfls/gfls-encoding.c:135 msgid "Chinese Simplified" msgstr "简体中文" #: gfls/gfls-encoding.c:136 msgid "Georgian" msgstr "格鲁吉亚语" #: gfls/gfls-encoding.c:142 gfls/gfls-encoding.c:164 msgid "Hebrew" msgstr "希伯来语" #: gfls/gfls-encoding.c:151 msgid "Cyrillic/Ukrainian" msgstr "西里尔文/乌克兰语" #: gfls/gfls-encoding.c:154 gfls/gfls-encoding.c:157 gfls/gfls-encoding.c:167 msgid "Vietnamese" msgstr "越南语" #: gfls/gfls-encoding.c:155 msgid "Thai" msgstr "泰语" #: gfls/gfls-encoding.c:434 msgid "Unknown" msgstr "未知" #. Translators: This is the sorted list of encodings used by #. * libgedit-gfls for automatic detection of the file encoding. You may #. * want to customize it adding encodings that are common in your #. * country, for instance the GB18030 encoding for the Chinese #. * translation. You may also want to remove the ISO-8859-15 encoding #. * (covering English and most Western European languages) if you think #. * people in your country will rarely use it. 'CURRENT' is a magic value #. * used by libgedit-gfls and it represents the encoding for the current #. * locale, so please don't translate the 'CURRENT' term. Keep the same #. * format: square brackets, single quotes, commas. #. #: gfls/gfls-encoding.c:793 msgid "['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']" msgstr "['UTF-8', 'CURRENT', 'GB18030', 'GBK', 'ISO-8859-15', 'UTF-16']" #: gfls/gfls-encoding-converter.c:308 msgid "An invalid byte has been encountered during character set conversion." msgstr "在字符集转换期间遇到了无效字节。" #: gfls/gfls-error.c:27 msgid "The size of the file is too big." msgstr "该文件太大了。" #: gfls/gfls-error.c:35 msgid "Limit on the number of bytes to read reached." msgstr "已达到字节数读取限制。" #: gfls/gfls-error.c:43 msgid "The content is not encoded in UTF-8." msgstr "该内容不是 UTF-8 编码。" #: gfls/gfls-error.c:51 msgid "The content contains a very long line." msgstr "该内容包含一个非常长的文本行。" #: gfls/gfls-iconv.c:141 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported." msgstr "不支持从字符集“%s”转换到“%s”。" #: gfls/gfls-iconv.c:150 #, c-format msgid "Failed to open a character set converter from “%s” to “%s”: %s" msgstr "打开从“%s”向“%s”的字符集转换器失败:%s" #: gfls/gfls-iconv.c:220 #, c-format msgid "Error during character set conversion: %s" msgstr "字符集转换时出错:%s" #: gfls/gfls-iconv.c:312 #, c-format msgid "Failed to close the character set converter: %s" msgstr "关闭字符集转换器失败:%s" #: gfls/gfls-unsaved-document-titles.c:61 #, c-format msgid "Unsaved Document %d" msgstr "未保存文档 %d" #, c-format #~ msgid "A number of nonreversible conversions have been performed." #~ msgstr "已执行一些不可逆的转换。" #~ msgid "No memory available." #~ msgstr "无可用内存。" #, c-format #~ msgid "%s (%s)" #~ msgstr "%s(%s)" libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/000077500000000000000000000000001526404376200227125ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/interactive-tests/000077500000000000000000000000001526404376200263675ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/interactive-tests/gfls-gui.c000066400000000000000000000141641526404376200302560ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #include /* 100 MiB */ #define FILE_SIZE_HARD_LIMIT (100 * 1024 * 1024) /* Number of bytes per line. 80 is for testing purposes ;-) */ #define VERY_LONG_LINE_LIMIT (80) typedef struct { GtkApplicationWindow *window; GtkTextView *view; GtkSpinButton *file_size_limit_spin_button; GFile *file; } ProgramData; static ProgramData * program_data_new (void) { return g_new0 (ProgramData, 1); } static void program_data_free (ProgramData *program_data) { if (program_data != NULL) { g_clear_object (&program_data->file); g_free (program_data); } } static GtkWidget * create_file_size_limit_spin_button (ProgramData *program_data) { GtkGrid *hgrid; GtkWidget *label; g_assert (program_data->file_size_limit_spin_button == NULL); hgrid = GTK_GRID (gtk_grid_new ()); gtk_grid_set_column_spacing (hgrid, 6); label = gtk_label_new ("File size limit:"); gtk_container_add (GTK_CONTAINER (hgrid), label); program_data->file_size_limit_spin_button = GTK_SPIN_BUTTON (gtk_spin_button_new_with_range (0.0, FILE_SIZE_HARD_LIMIT, 1.0)); gtk_container_add (GTK_CONTAINER (hgrid), GTK_WIDGET (program_data->file_size_limit_spin_button)); return GTK_WIDGET (hgrid); } static gsize get_file_size_limit (ProgramData *program_data) { gint value; value = gtk_spin_button_get_value_as_int (program_data->file_size_limit_spin_button); g_return_val_if_fail (value >= 0, 0); return value; } static void set_text_buffer_content (ProgramData *program_data, GBytes *bytes) { const gchar *text; gsize n_bytes; GtkTextBuffer *buffer; text = g_bytes_get_data (bytes, &n_bytes); buffer = gtk_text_view_get_buffer (program_data->view); gtk_text_buffer_set_text (buffer, text, n_bytes); } static void load_file_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GFile *file = G_FILE (source_object); ProgramData *program_data = user_data; GBytes *bytes; GError *error = NULL; bytes = gfls_loader_basic_load_finish (file, result, &error); if (error != NULL) { g_printerr ("%s\n", error->message); g_clear_error (&error); g_bytes_unref (bytes); return; } set_text_buffer_content (program_data, bytes); g_bytes_unref (bytes); } static void load_file (ProgramData *program_data) { gfls_loader_basic_load_async (program_data->file, get_file_size_limit (program_data), VERY_LONG_LINE_LIMIT, G_PRIORITY_DEFAULT, NULL, load_file_cb, program_data); } static void open_file_chooser_response_cb (GtkFileChooserNative *open_file_chooser, gint response_id, ProgramData *program_data) { if (response_id == GTK_RESPONSE_ACCEPT) { gchar *parse_name; g_clear_object (&program_data->file); program_data->file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (open_file_chooser)); parse_name = g_file_get_parse_name (program_data->file); g_print ("Open file: %s\n", parse_name); g_free (parse_name); load_file (program_data); } g_object_unref (open_file_chooser); } static void open_file_button_clicked_cb (GtkButton *open_file_button, ProgramData *program_data) { GtkFileChooserNative *file_chooser; file_chooser = gtk_file_chooser_native_new ("Open File", GTK_WINDOW (program_data->window), GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL); g_signal_connect (file_chooser, "response", G_CALLBACK (open_file_chooser_response_cb), program_data); gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (file_chooser), TRUE); gtk_native_dialog_show (GTK_NATIVE_DIALOG (file_chooser)); } static GtkWidget * create_open_file_button (ProgramData *program_data) { GtkButton *open_file_button; open_file_button = GTK_BUTTON (gtk_button_new_with_label ("Open File")); g_signal_connect (open_file_button, "clicked", G_CALLBACK (open_file_button_clicked_cb), program_data); return GTK_WIDGET (open_file_button); } static GtkWidget * create_side_panel (ProgramData *program_data) { GtkGrid *vgrid; vgrid = GTK_GRID (gtk_grid_new ()); gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL); gtk_grid_set_row_spacing (vgrid, 6); gtk_container_add (GTK_CONTAINER (vgrid), create_file_size_limit_spin_button (program_data)); gtk_container_add (GTK_CONTAINER (vgrid), create_open_file_button (program_data)); return GTK_WIDGET (vgrid); } static GtkWidget * create_view (ProgramData *program_data) { GtkWidget *scrolled_window; g_assert (program_data->view == NULL); program_data->view = GTK_TEXT_VIEW (gtk_text_view_new ()); gtk_text_view_set_monospace (program_data->view, TRUE); g_object_set (program_data->view, "expand", TRUE, NULL); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (program_data->view)); return scrolled_window; } static void activate_cb (GApplication *g_app, ProgramData *program_data) { GtkGrid *hgrid; g_assert (program_data->window == NULL); program_data->window = GTK_APPLICATION_WINDOW (gtk_application_window_new (GTK_APPLICATION (g_app))); gtk_window_set_default_size (GTK_WINDOW (program_data->window), 800, 600); hgrid = GTK_GRID (gtk_grid_new ()); gtk_container_add (GTK_CONTAINER (hgrid), create_side_panel (program_data)); gtk_container_add (GTK_CONTAINER (hgrid), create_view (program_data)); gtk_container_add (GTK_CONTAINER (program_data->window), GTK_WIDGET (hgrid)); gtk_widget_show_all (GTK_WIDGET (program_data->window)); } int main (int argc, char **argv) { GtkApplication *app; ProgramData *program_data; int exit_status; setlocale (LC_ALL, ""); gfls_init (); app = gtk_application_new (NULL, G_APPLICATION_DEFAULT_FLAGS); program_data = program_data_new (); g_signal_connect (app, "activate", G_CALLBACK (activate_cb), program_data); exit_status = g_application_run (G_APPLICATION (app), argc, argv); g_object_unref (app); program_data_free (program_data); gfls_finalize (); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/interactive-tests/gfls-program.c000066400000000000000000000062401526404376200311350ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include typedef struct { GFile *file; } ProgramData; static ProgramData * program_data_new (void) { return g_new0 (ProgramData, 1); } static void program_data_free (ProgramData *program_data) { if (program_data != NULL) { g_clear_object (&program_data->file); g_free (program_data); } } static void quit_program (void) { g_application_release (g_application_get_default ()); } static void query_info_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GFile *file = G_FILE (source_object); GFileInfo *info; GError *error = NULL; info = g_file_query_info_finish (file, result, &error); if (error != NULL) { g_printerr ("Failed to query file informations: %s\n", error->message); g_clear_error (&error); goto out; } if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_TYPE)) { GFileType type; type = g_file_info_get_file_type (info); if (type == G_FILE_TYPE_REGULAR) { g_print ("Regular file.\n"); } else { g_print ("The file is not a regular file.\n"); } } if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)) { const gchar *display_name; display_name = g_file_info_get_display_name (info); g_print ("Display name: %s\n", display_name); } if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE)) { goffset n_bytes; n_bytes = g_file_info_get_size (info); g_print ("File size in bytes: %" G_GOFFSET_FORMAT "\n", n_bytes); } out: g_clear_object (&info); quit_program (); } static void launch_program (ProgramData *program_data) { g_application_hold (g_application_get_default ()); g_file_query_info_async (program_data->file, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, NULL, query_info_cb, NULL); } static gint app_command_line_cb (GApplication *app, GApplicationCommandLine *command_line, gpointer user_data) { ProgramData *program_data = user_data; gchar **argv; gint argc; gint exit_status = EXIT_SUCCESS; argv = g_application_command_line_get_arguments (command_line, &argc); if (argc != 2) { g_application_command_line_printerr (command_line, "Usage: %s \n", argv[0]); exit_status = EXIT_FAILURE; goto out; } program_data->file = g_application_command_line_create_file_for_arg (command_line, argv[1]); launch_program (program_data); out: g_strfreev (argv); return exit_status; } int main (int argc, char **argv) { GApplication *app; ProgramData *program_data; int exit_status; setlocale (LC_ALL, ""); app = g_application_new (NULL, G_APPLICATION_HANDLES_COMMAND_LINE); program_data = program_data_new (); g_signal_connect (app, "command-line", G_CALLBACK (app_command_line_cb), program_data); exit_status = g_application_run (app, argc, argv); g_object_unref (app); program_data_free (program_data); return exit_status; } gfls-test-race-read-content.c000066400000000000000000000127331526404376200336630ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/interactive-tests/* SPDX-FileCopyrightText: 2023 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include /* Purpose of this test program * ============================ * * To test the following race condition: * (1) Read a first block of bytes from a file (with GIO). * (2) Launch a timeout function (long enough to manually alter the file). * (3) With another program, alter the content of the file. E.g. with: * $ echo foobar > file * (4) When the timeout callback function is called, continue to read the file. * * And see what happens, how the programs behave, if errors are reported, etc. * * Result * ------ * * Absolutely no errors are reported. Even when closing the GFileInputStream. * * Solution * -------- * * Rely on the etag values provided by GIO to know if the file has been * externally modified. Worst case this is detected upon saving the file (show * an infobar at that moment). * * It can be desired to be able to open a file that is continuously modified by * another program, e.g. a log file. */ /* Read a string of 80 chars and nul-terminate it. * This is for testing purposes, so a short value is chosen. */ #define BUFFER_SIZE (81) typedef struct { GFile *file; GFileInputStream *input_stream; guint8 buffer[BUFFER_SIZE]; } ProgramData; static void read_next_chunk (ProgramData *program_data); static ProgramData * program_data_new (void) { ProgramData *program_data; program_data = g_new (ProgramData, 1); program_data->file = NULL; program_data->input_stream = NULL; /* Don't zero the buffer, it will anyway be nul-terminated manually. */ return program_data; } static void program_data_free (ProgramData *program_data) { if (program_data != NULL) { g_clear_object (&program_data->file); g_clear_object (&program_data->input_stream); g_free (program_data); } } static void quit_program (void) { g_application_release (g_application_get_default ()); } static void close_file_input_stream (ProgramData *program_data) { GError *error = NULL; g_print ("Closing file input stream.\n"); g_input_stream_close (G_INPUT_STREAM (program_data->input_stream), NULL, &error); if (error != NULL) { g_printerr ("Failed to close the file input stream: %s\n", error->message); g_clear_error (&error); } } static gboolean timeout_cb (gpointer user_data) { ProgramData *program_data = user_data; read_next_chunk (program_data); return G_SOURCE_REMOVE; } static void read_next_chunk_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { ProgramData *program_data = user_data; GError *error = NULL; gssize n_bytes_read; n_bytes_read = g_input_stream_read_finish (G_INPUT_STREAM (program_data->input_stream), result, &error); if (error != NULL) { g_printerr ("Failed to read the next chunk of content: %s\n", error->message); g_clear_error (&error); quit_program (); return; } if (n_bytes_read == 0) { g_print ("Finished reading.\n"); close_file_input_stream (program_data); quit_program (); return; } g_assert (n_bytes_read > 0); g_assert (n_bytes_read < BUFFER_SIZE); program_data->buffer[n_bytes_read] = '\0'; g_print ("Next chunk read:\n%s\n", program_data->buffer); g_timeout_add_seconds (15, timeout_cb, program_data); } static void read_next_chunk (ProgramData *program_data) { g_input_stream_read_async (G_INPUT_STREAM (program_data->input_stream), program_data->buffer, BUFFER_SIZE - 1, /* -1 to keep one byte to nul-terminate the string. */ G_PRIORITY_DEFAULT, NULL, read_next_chunk_cb, program_data); } static void file_read_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GFile *file = G_FILE (source_object); ProgramData *program_data = user_data; GError *error = NULL; g_assert (program_data->input_stream == NULL); program_data->input_stream = g_file_read_finish (file, result, &error); if (error != NULL) { g_printerr ("Failed to open file for reading: %s\n", error->message); g_clear_error (&error); quit_program (); return; } read_next_chunk (program_data); } static void launch_program (ProgramData *program_data) { g_application_hold (g_application_get_default ()); g_file_read_async (program_data->file, G_PRIORITY_DEFAULT, NULL, file_read_cb, program_data); } static gint app_command_line_cb (GApplication *app, GApplicationCommandLine *command_line, gpointer user_data) { ProgramData *program_data = user_data; gchar **argv; gint argc; gint exit_status = EXIT_SUCCESS; argv = g_application_command_line_get_arguments (command_line, &argc); if (argc != 2) { g_application_command_line_printerr (command_line, "Usage: %s \n", argv[0]); exit_status = EXIT_FAILURE; goto out; } program_data->file = g_application_command_line_create_file_for_arg (command_line, argv[1]); launch_program (program_data); out: g_strfreev (argv); return exit_status; } int main (int argc, char **argv) { GApplication *app; ProgramData *program_data; int exit_status; setlocale (LC_ALL, ""); app = g_application_new (NULL, G_APPLICATION_HANDLES_COMMAND_LINE); program_data = program_data_new (); g_signal_connect (app, "command-line", G_CALLBACK (app_command_line_cb), program_data); exit_status = g_application_run (app, argc, argv); g_object_unref (app); program_data_free (program_data); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/interactive-tests/meson.build000066400000000000000000000004701526404376200305320ustar00rootroot00000000000000executable( 'gfls-program', 'gfls-program.c', dependencies: GFLS_DEPS, ) executable( 'gfls-test-race-read-content', 'gfls-test-race-read-content.c', dependencies: GFLS_DEPS, ) if GTK3_DEP.found() executable( 'gfls-gui', 'gfls-gui.c', dependencies: [GFLS_LIB_DEP, GTK3_DEP], ) endif libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/meson.build000066400000000000000000000000611526404376200250510ustar00rootroot00000000000000subdir('interactive-tests') subdir('unit-tests') libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/000077500000000000000000000000001526404376200250315ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/meson.build000066400000000000000000000006701526404376200271760ustar00rootroot00000000000000unit_tests = [ 'test-attribute-keys', 'test-byte-array', 'test-encoding', 'test-encoding-conversion', 'test-encoding-converter', 'test-iconv', 'test-input-stream', 'test-unsaved-document-titles', 'test-utf8', 'test-utils', 'test-validated-string', ] foreach test_name : unit_tests test_exe = executable( test_name, test_name + '.c', dependencies: GFLS_LIB_DEP ) test(test_name, test_exe) endforeach libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/test-attribute-keys.c000066400000000000000000000016551526404376200311350ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void test_basics (void) { GflsAttributeKeys *keys = gfls_attribute_keys_new (); gchar *result; result = gfls_attribute_keys_to_string (keys); g_assert_null (result); gfls_attribute_keys_add (keys, "standard::display-name"); result = gfls_attribute_keys_to_string (keys); g_assert_cmpstr (result, ==, "standard::display-name"); g_free (result); gfls_attribute_keys_add (keys, "access::*"); result = gfls_attribute_keys_to_string (keys); g_assert_cmpstr (result, ==, "standard::display-name,access::*"); g_free (result); g_object_unref (keys); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/AttributeKeys/basics", test_basics); exit_status = g_test_run (); gfls_finalize (); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/test-byte-array.c000066400000000000000000000046731526404376200302430ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void test_empty (void) { GflsByteArray *byte_array; GBytes *bytes; const guint8 data = 'a'; /* Don't append */ byte_array = gfls_byte_array_new (); bytes = gfls_byte_array_free_to_bytes (byte_array); g_assert_null (bytes); /* Append nothing */ byte_array = gfls_byte_array_new (); gfls_byte_array_append (byte_array, NULL, 0); gfls_byte_array_append (byte_array, NULL, 1); gfls_byte_array_append (byte_array, &data, 0); bytes = gfls_byte_array_free_to_bytes (byte_array); g_assert_null (bytes); } static void test_single_byte (void) { GflsByteArray *byte_array; GBytes *bytes; const guint8 data = 'a'; const guint8 *result_data; byte_array = gfls_byte_array_new (); gfls_byte_array_append (byte_array, &data, 1); bytes = gfls_byte_array_free_to_bytes (byte_array); g_assert_nonnull (bytes); g_assert_cmpuint (g_bytes_get_size (bytes), ==, 1); result_data = g_bytes_get_data (bytes, NULL); g_assert_cmpuint (result_data[0], ==, 'a'); g_assert_cmpuint (result_data[1], ==, '\0'); g_bytes_unref (bytes); } static void test_several_appends (void) { GflsByteArray *byte_array; GBytes *bytes; gchar *str; const guint8 nul_byte = '\0'; const guint8 *result_data; gint i; byte_array = gfls_byte_array_new (); str = g_strnfill (1024, 'b'); gfls_byte_array_append (byte_array, (const guint8 *) str, 1024); gfls_byte_array_append (byte_array, &nul_byte, 1); g_free (str); str = g_strnfill (1024, 'c'); gfls_byte_array_append (byte_array, (const guint8 *) str, 1024); bytes = gfls_byte_array_free_to_bytes (byte_array); g_assert_nonnull (bytes); g_assert_cmpuint (g_bytes_get_size (bytes), ==, 2049); result_data = g_bytes_get_data (bytes, NULL); for (i = 0; i < 1024; i++) { g_assert_cmpuint (result_data[i], ==, 'b'); } g_assert_cmpuint (result_data[1024], ==, '\0'); for (i = 1025; i < 2049; i++) { g_assert_cmpuint (result_data[i], ==, 'c'); } g_assert_cmpuint (result_data[2049], ==, '\0'); g_bytes_unref (bytes); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/ByteArray/empty", test_empty); g_test_add_func ("/ByteArray/single_byte", test_single_byte); g_test_add_func ("/ByteArray/several_appends", test_several_appends); exit_status = g_test_run (); gfls_finalize (); return exit_status; } test-encoding-conversion.c000066400000000000000000000023051526404376200320440ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/* SPDX-FileCopyrightText: 2025-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void test_try_convert_success (void) { GBytes *input_bytes; gboolean ret; input_bytes = g_bytes_new_static ("a", 1); ret = gfls_encoding_try_convert (input_bytes, "UTF-8", "UTF-8"); g_assert_true (ret); g_bytes_unref (input_bytes); } static void test_try_convert_illegal_sequence (void) { guint8 input_buffer[1]; GBytes *input_bytes; gboolean ret; // 255, aka "1111 1111" in binary and 0xFF in hexadecimal. // In UTF-8, this is an invalid byte. // See https://en.wikipedia.org/wiki/UTF-8 input_buffer[0] = 255; input_bytes = g_bytes_new (input_buffer, 1); ret = gfls_encoding_try_convert (input_bytes, "UTF-8", "UTF-8"); g_assert_false (ret); g_bytes_unref (input_bytes); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/EncodingConversion/try_convert_success", test_try_convert_success); g_test_add_func ("/EncodingConversion/try_convert_illegal_sequence", test_try_convert_illegal_sequence); exit_status = g_test_run (); gfls_finalize (); return exit_status; } test-encoding-converter.c000066400000000000000000000333741526404376200317000ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include typedef struct { GBytes *expected_bytes; guint expected_is_valid : 1; } ExpectedCallbackOutput; typedef struct { ExpectedCallbackOutput **expected_callback_output; guint current_callback_num; guint expected_total_callbacks_count; } CallbackData; static ExpectedCallbackOutput * expected_callback_output_new_simple (const gchar *data, gboolean is_valid) { ExpectedCallbackOutput *expected_callback_output; expected_callback_output = g_new0 (ExpectedCallbackOutput, 1); expected_callback_output->expected_bytes = g_bytes_new (data, strlen (data)); expected_callback_output->expected_is_valid = is_valid != FALSE; return expected_callback_output; } static void expected_callback_output_free (ExpectedCallbackOutput *expected_callback_output) { if (expected_callback_output != NULL) { g_bytes_unref (expected_callback_output->expected_bytes); g_free (expected_callback_output); } } static CallbackData * callback_data_new (guint expected_total_callbacks_count) { CallbackData *data; data = g_new0 (CallbackData, 1); /* +1 for NULL-termination. */ data->expected_callback_output = g_new0 (ExpectedCallbackOutput*, expected_total_callbacks_count + 1); data->current_callback_num = 0; data->expected_total_callbacks_count = expected_total_callbacks_count; return data; } static void callback_data_free (CallbackData *data) { guint i; if (data == NULL) { return; } for (i = 0; data->expected_callback_output[i] != NULL; i++) { expected_callback_output_free (data->expected_callback_output[i]); } g_free (data->expected_callback_output); g_free (data); } static void converter_cb (GBytes *bytes, gboolean is_valid, gpointer user_data) { CallbackData *callback_data = user_data; ExpectedCallbackOutput *expected_callback_output; g_assert_cmpuint (callback_data->current_callback_num, <, callback_data->expected_total_callbacks_count); expected_callback_output = callback_data->expected_callback_output[callback_data->current_callback_num]; g_assert_true (g_bytes_equal (bytes, expected_callback_output->expected_bytes)); g_assert_cmpint (is_valid, ==, expected_callback_output->expected_is_valid); callback_data->current_callback_num++; } static void test_new_and_free (void) { GflsEncodingConverter *converter; converter = gfls_encoding_converter_new (); g_object_unref (converter); } static void test_set_and_get_allow_invalid_bytes (void) { GflsEncodingConverter *converter; converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, TRUE); g_assert_true (gfls_encoding_converter_get_allow_invalid_bytes (converter)); gfls_encoding_converter_set_allow_invalid_bytes (converter, FALSE); g_assert_false (gfls_encoding_converter_get_allow_invalid_bytes (converter)); g_object_unref (converter); } static void test_lossy_conversion_after_no_input (void) { GflsEncodingConverter *converter; converter = gfls_encoding_converter_new (); g_assert_false (gfls_encoding_converter_get_lossy_conversion (converter)); g_object_unref (converter); } static void test_open (void) { GflsEncodingConverter *converter; gboolean ok; GError *error = NULL; converter = gfls_encoding_converter_new (); ok = gfls_encoding_converter_open (converter, "UTF-8", "UTF-8", &error); g_assert_true (ok); g_assert_no_error (error); g_object_unref (converter); converter = gfls_encoding_converter_new (); ok = gfls_encoding_converter_open (converter, "UTF-8", "CANNOT_POSSIBLY_WORK", &error); g_assert_false (ok); g_assert_nonnull (error); g_clear_error (&error); g_object_unref (converter); } static void test_basic_feed (void) { GflsEncodingConverter *converter; CallbackData *data; gboolean ok; GError *error = NULL; converter = gfls_encoding_converter_new (); data = callback_data_new (1); data->expected_callback_output[0] = expected_callback_output_new_simple ("abc", TRUE); gfls_encoding_converter_set_allow_invalid_bytes (converter, FALSE); gfls_encoding_converter_set_callback (converter, converter_cb, data); ok = gfls_encoding_converter_open (converter, "UTF-8", "ASCII", &error); g_assert_true (ok); g_assert_no_error (error); ok = gfls_encoding_converter_feed (converter, (const guint8 *) "abc", 3, &error); g_assert_true (ok); g_assert_no_error (error); ok = gfls_encoding_converter_finish_feeding (converter, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, data->expected_total_callbacks_count); g_assert_false (gfls_encoding_converter_get_lossy_conversion (converter)); g_object_unref (converter); callback_data_free (data); } static void test_feed_incomplete_multi_byte_sequence (void) { GflsEncodingConverter *converter; CallbackData *data; gboolean ok; GError *error = NULL; converter = gfls_encoding_converter_new (); data = callback_data_new (1); /* "é" in UTF-8 (two bytes). */ data->expected_callback_output[0] = expected_callback_output_new_simple ("\xC3\xA9", TRUE); gfls_encoding_converter_set_allow_invalid_bytes (converter, TRUE); gfls_encoding_converter_set_callback (converter, converter_cb, data); ok = gfls_encoding_converter_open (converter, "UTF-8", "UTF-8", &error); g_assert_true (ok); g_assert_no_error (error); ok = gfls_encoding_converter_feed (converter, (const guint8 *) "\xC3", 1, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, 0); ok = gfls_encoding_converter_feed (converter, (const guint8 *) "\xA9", 1, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, 1); ok = gfls_encoding_converter_finish_feeding (converter, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, data->expected_total_callbacks_count); g_assert_false (gfls_encoding_converter_get_lossy_conversion (converter)); g_object_unref (converter); callback_data_free (data); } static void test_invalid_byte_error_during_feed (void) { GflsEncodingConverter *converter; GError *error = NULL; gboolean ok; converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, FALSE); ok = gfls_encoding_converter_open (converter, "UTF-8", "UTF-8", &error); g_assert_true (ok); g_assert_no_error (error); /* This is an invalid byte in UTF-8. See test-iconv.c for more infos. */ ok = gfls_encoding_converter_feed (converter, (const guint8 *) "\xFF", 1, &error); g_assert_false (ok); g_assert_nonnull (error); g_clear_error (&error); g_object_unref (converter); } static void test_invalid_byte_error_during_finish_feeding (void) { GflsEncodingConverter *converter; GError *error = NULL; gboolean ok; converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, FALSE); ok = gfls_encoding_converter_open (converter, "UTF-8", "UTF-8", &error); g_assert_true (ok); g_assert_no_error (error); /* Feed an incomplete multi-byte sequence. */ ok = gfls_encoding_converter_feed (converter, (const guint8 *) "\xC3", 1, &error); g_assert_true (ok); g_assert_no_error (error); ok = gfls_encoding_converter_finish_feeding (converter, &error); g_assert_false (ok); g_assert_nonnull (error); g_clear_error (&error); g_object_unref (converter); } static void test_invalid_chunk_during_feed (void) { GflsEncodingConverter *converter; CallbackData *data; GError *error = NULL; gboolean ok; converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, TRUE); data = callback_data_new (2); data->expected_callback_output[0] = expected_callback_output_new_simple ("abc", TRUE); data->expected_callback_output[1] = expected_callback_output_new_simple ("\xFF", FALSE); gfls_encoding_converter_set_callback (converter, converter_cb, data); ok = gfls_encoding_converter_open (converter, "UTF-8", "UTF-8", &error); g_assert_true (ok); g_assert_no_error (error); /* 0xFF is an invalid byte in UTF-8. */ ok = gfls_encoding_converter_feed (converter, (const guint8 *) "abc\xFF", 4, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, 2); ok = gfls_encoding_converter_finish_feeding (converter, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, data->expected_total_callbacks_count); g_assert_false (gfls_encoding_converter_get_lossy_conversion (converter)); g_object_unref (converter); callback_data_free (data); } static void test_invalid_chunk_during_finish_feeding (void) { GflsEncodingConverter *converter; CallbackData *data; GError *error = NULL; gboolean ok; converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, TRUE); data = callback_data_new (1); /* The first byte of "é" in UTF-8 (two bytes). */ data->expected_callback_output[0] = expected_callback_output_new_simple ("\xC3", FALSE); gfls_encoding_converter_set_callback (converter, converter_cb, data); ok = gfls_encoding_converter_open (converter, "UTF-8", "UTF-8", &error); g_assert_true (ok); g_assert_no_error (error); /* Feed an incomplete multi-byte sequence. */ ok = gfls_encoding_converter_feed (converter, (const guint8 *) "\xC3", 1, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, 0); ok = gfls_encoding_converter_finish_feeding (converter, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, 1); g_assert_cmpuint (data->current_callback_num, ==, data->expected_total_callbacks_count); g_assert_false (gfls_encoding_converter_get_lossy_conversion (converter)); g_object_unref (converter); callback_data_free (data); } static void test_output_buffer_full (void) { GflsEncodingConverter *converter; CallbackData *data; gchar *first_chunk_str; gchar *input_str; GError *error = NULL; gboolean ok; converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, TRUE); data = callback_data_new (2); /* 8 KiB - 1 (this is an implementation detail). */ first_chunk_str = g_strnfill (8191, 'a'); data->expected_callback_output[0] = expected_callback_output_new_simple (first_chunk_str, TRUE); data->expected_callback_output[1] = expected_callback_output_new_simple ("bcd", TRUE); gfls_encoding_converter_set_callback (converter, converter_cb, data); ok = gfls_encoding_converter_open (converter, "ASCII", "ASCII", &error); g_assert_true (ok); g_assert_no_error (error); input_str = g_strconcat (first_chunk_str, "bcd", NULL); ok = gfls_encoding_converter_feed (converter, (const guint8 *) input_str, strlen (input_str), &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, 2); ok = gfls_encoding_converter_finish_feeding (converter, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, data->expected_total_callbacks_count); g_assert_false (gfls_encoding_converter_get_lossy_conversion (converter)); g_object_unref (converter); callback_data_free (data); g_free (first_chunk_str); g_free (input_str); } static void test_lossy_conversion (void) { GflsEncodingConverter *converter; CallbackData *data; GError *error = NULL; gboolean ok; converter = gfls_encoding_converter_new (); gfls_encoding_converter_set_allow_invalid_bytes (converter, TRUE); data = callback_data_new (1); /* Depends on the iconv implementation. The '?' could be something else. */ data->expected_callback_output[0] = expected_callback_output_new_simple ("?", TRUE); gfls_encoding_converter_set_callback (converter, converter_cb, data); ok = gfls_encoding_converter_open (converter, "UTF-8", "ASCII//TRANSLIT", &error); g_assert_true (ok); g_assert_no_error (error); /* Feed "é" in UTF-8. */ ok = gfls_encoding_converter_feed (converter, (const guint8 *) "\xC3\xA9", 2, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, 1); ok = gfls_encoding_converter_finish_feeding (converter, &error); g_assert_true (ok); g_assert_no_error (error); g_assert_cmpuint (data->current_callback_num, ==, data->expected_total_callbacks_count); g_assert_true (gfls_encoding_converter_get_lossy_conversion (converter)); g_object_unref (converter); callback_data_free (data); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/EncodingConverter/new_and_free", test_new_and_free); g_test_add_func ("/EncodingConverter/set_and_get_allow_invalid_bytes", test_set_and_get_allow_invalid_bytes); g_test_add_func ("/EncodingConverter/lossy_conversion_after_no_input", test_lossy_conversion_after_no_input); g_test_add_func ("/EncodingConverter/open", test_open); g_test_add_func ("/EncodingConverter/basic_feed", test_basic_feed); g_test_add_func ("/EncodingConverter/feed_incomplete_multi_byte_sequence", test_feed_incomplete_multi_byte_sequence); g_test_add_func ("/EncodingConverter/invalid_byte_error_during_feed", test_invalid_byte_error_during_feed); g_test_add_func ("/EncodingConverter/invalid_byte_error_during_finish_feeding", test_invalid_byte_error_during_finish_feeding); g_test_add_func ("/EncodingConverter/invalid_chunk_during_feed", test_invalid_chunk_during_feed); g_test_add_func ("/EncodingConverter/invalid_chunk_during_finish_feeding", test_invalid_chunk_during_finish_feeding); g_test_add_func ("/EncodingConverter/output_buffer_full", test_output_buffer_full); g_test_add_func ("/EncodingConverter/lossy_conversion", test_lossy_conversion); exit_status = g_test_run (); gfls_finalize (); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/test-encoding.c000066400000000000000000000031321526404376200277370ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2014-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void test_remove_duplicates (void) { GSList *list = NULL; GflsEncoding *utf8; GflsEncoding *iso; utf8 = gfls_encoding_new_utf8 (); iso = gfls_encoding_new ("ISO-8859-15"); /* Before: [UTF-8, ISO-8859-15, UTF-8] */ list = g_slist_prepend (list, gfls_encoding_copy (utf8)); list = g_slist_prepend (list, gfls_encoding_copy (iso)); list = g_slist_prepend (list, gfls_encoding_copy (utf8)); /* After: [UTF-8, ISO-8859-15] */ list = gfls_encoding_remove_duplicates (list, GFLS_ENCODING_DUPLICATES_KEEP_FIRST); g_assert_cmpint (2, ==, g_slist_length (list)); g_assert_true (gfls_encoding_equals (list->data, utf8)); g_assert_true (gfls_encoding_equals (list->next->data, iso)); /* Before: [UTF-8, ISO-8859-15, UTF-8] */ list = g_slist_append (list, gfls_encoding_copy (utf8)); /* After: [ISO-8859-15, UTF-8] */ list = gfls_encoding_remove_duplicates (list, GFLS_ENCODING_DUPLICATES_KEEP_LAST); g_assert_cmpint (2, ==, g_slist_length (list)); g_assert_true (gfls_encoding_equals (list->data, iso)); g_assert_true (gfls_encoding_equals (list->next->data, utf8)); g_slist_free_full (list, (GDestroyNotify)gfls_encoding_free); gfls_encoding_free (utf8); gfls_encoding_free (iso); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/Encoding/remove_duplicates", test_remove_duplicates); exit_status = g_test_run (); gfls_finalize (); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/test-iconv.c000066400000000000000000000244531526404376200273000ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2025 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void test_new_and_free (void) { GflsIconv *conv; conv = gfls_iconv_new (); gfls_iconv_free (conv); gfls_iconv_free (NULL); } static void test_open_and_close (void) { GflsIconv *conv; gboolean ok; GError *error = NULL; /* All OK */ conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "UTF-8", "UTF-8", &error); g_assert_true (ok); g_assert_no_error (error); ok = gfls_iconv_close (conv, &error); g_assert_true (ok); g_assert_no_error (error); gfls_iconv_free (conv); /* Open not OK */ conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "UTF-8", "CANNOT_POSSIBLY_WORK", &error); g_assert_false (ok); g_assert_nonnull (error); g_clear_error (&error); ok = gfls_iconv_close (conv, &error); g_assert_true (ok); g_assert_no_error (error); gfls_iconv_free (conv); } static void test_feed_ok (void) { GflsIconv *conv; gboolean ok; gsize input_buffer_size; gsize output_buffer_size; gchar *input_buffer; gchar *output_buffer; gchar *input_buffer_pos; gchar *output_buffer_pos; gsize input_buffer_n_bytes_left; gsize output_buffer_n_bytes_left; GflsIconvResult result; GError *error = NULL; conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "UTF-8", "UTF-8", NULL); g_assert_true (ok); input_buffer_size = 1; input_buffer = g_malloc (input_buffer_size); input_buffer[0] = 'a'; output_buffer_size = 32; output_buffer = g_malloc (output_buffer_size); input_buffer_pos = input_buffer; output_buffer_pos = output_buffer; input_buffer_n_bytes_left = input_buffer_size; output_buffer_n_bytes_left = output_buffer_size; result = gfls_iconv_feed (conv, &input_buffer_pos, &input_buffer_n_bytes_left, &output_buffer_pos, &output_buffer_n_bytes_left, &error); g_assert_true (result == GFLS_ICONV_RESULT_OK); g_assert_no_error (error); g_assert_cmpuint (input_buffer_n_bytes_left, ==, 0); g_assert_cmpuint (output_buffer_n_bytes_left, ==, 31); g_assert_true (input_buffer_pos == input_buffer + 1); g_assert_true (output_buffer_pos == output_buffer + 1); gfls_iconv_free (conv); g_free (input_buffer); g_free (output_buffer); } static void test_feed_output_buffer_full (void) { GflsIconv *conv; gboolean ok; gsize input_buffer_size; gsize output_buffer_size; gchar *input_buffer; gchar *output_buffer; gchar *input_buffer_pos; gchar *output_buffer_pos; gsize input_buffer_n_bytes_left; gsize output_buffer_n_bytes_left; GflsIconvResult result; GError *error = NULL; conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "UTF-8", "UTF-8", NULL); g_assert_true (ok); input_buffer_size = 20; input_buffer = g_malloc (input_buffer_size); memset (input_buffer, 'a', input_buffer_size); output_buffer_size = 16; output_buffer = g_malloc (output_buffer_size); input_buffer_pos = input_buffer; output_buffer_pos = output_buffer; input_buffer_n_bytes_left = input_buffer_size; output_buffer_n_bytes_left = output_buffer_size; result = gfls_iconv_feed (conv, &input_buffer_pos, &input_buffer_n_bytes_left, &output_buffer_pos, &output_buffer_n_bytes_left, &error); g_assert_true (result == GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL); g_assert_no_error (error); g_assert_cmpuint (input_buffer_n_bytes_left, ==, 4); g_assert_cmpuint (output_buffer_n_bytes_left, ==, 0); g_assert_true (input_buffer_pos == input_buffer + 16); g_assert_true (output_buffer_pos == output_buffer + 16); gfls_iconv_free (conv); g_free (input_buffer); g_free (output_buffer); } static void test_feed_incomplete_input (void) { GflsIconv *conv; gboolean ok; gsize input_buffer_size; gsize output_buffer_size; guint8 *input_buffer_raw; gchar *input_buffer; gchar *output_buffer; gchar *input_buffer_pos; gchar *output_buffer_pos; gsize input_buffer_n_bytes_left; gsize output_buffer_n_bytes_left; GflsIconvResult result; GError *error = NULL; conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "UTF-8", "UTF-8", NULL); g_assert_true (ok); input_buffer_size = 1; input_buffer_raw = g_malloc (input_buffer_size); input_buffer = (gchar *) input_buffer_raw; // 195, aka "1100 0011" in binary and 0xC3 in hexadecimal. // In UTF-8, this is a first (valid) byte of a two-bytes encoded // character. // // For example this is the first byte of "é" // Latin Small Letter E With Acute (U+00E9) // which is encoded in UTF-8 as 0xC3 0xA9. // // For a two-bytes UTF-8 character, refer to Wikipedia: // First code point: U+0080 // Last code point: U+07FF // Byte 1: 110xxxyy // Byte 2: 10yyzzzz // See https://en.wikipedia.org/wiki/UTF-8 input_buffer_raw[0] = 195; output_buffer_size = 32; output_buffer = g_malloc (output_buffer_size); input_buffer_pos = input_buffer; output_buffer_pos = output_buffer; input_buffer_n_bytes_left = input_buffer_size; output_buffer_n_bytes_left = output_buffer_size; result = gfls_iconv_feed (conv, &input_buffer_pos, &input_buffer_n_bytes_left, &output_buffer_pos, &output_buffer_n_bytes_left, &error); g_assert_true (result == GFLS_ICONV_RESULT_INCOMPLETE_INPUT); g_assert_no_error (error); g_assert_cmpuint (input_buffer_n_bytes_left, ==, 1); g_assert_cmpuint (output_buffer_n_bytes_left, ==, 32); g_assert_true (input_buffer_pos == input_buffer); g_assert_true (output_buffer_pos == output_buffer); gfls_iconv_free (conv); g_free (input_buffer_raw); g_free (output_buffer); } static void test_feed_illegal_sequence (void) { GflsIconv *conv; gboolean ok; gsize input_buffer_size; gsize output_buffer_size; guint8 *input_buffer_raw; gchar *input_buffer; gchar *output_buffer; gchar *input_buffer_pos; gchar *output_buffer_pos; gsize input_buffer_n_bytes_left; gsize output_buffer_n_bytes_left; GflsIconvResult result; GError *error = NULL; conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "UTF-8", "UTF-8", NULL); g_assert_true (ok); input_buffer_size = 1; input_buffer_raw = g_malloc (input_buffer_size); input_buffer = (gchar *) input_buffer_raw; // 255, aka "1111 1111" in binary and 0xFF in hexadecimal. // In UTF-8, this is an invalid byte. // See https://en.wikipedia.org/wiki/UTF-8 input_buffer_raw[0] = 255; output_buffer_size = 32; output_buffer = g_malloc (output_buffer_size); input_buffer_pos = input_buffer; output_buffer_pos = output_buffer; input_buffer_n_bytes_left = input_buffer_size; output_buffer_n_bytes_left = output_buffer_size; result = gfls_iconv_feed (conv, &input_buffer_pos, &input_buffer_n_bytes_left, &output_buffer_pos, &output_buffer_n_bytes_left, &error); g_assert_true (result == GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE); g_assert_no_error (error); g_assert_cmpuint (input_buffer_n_bytes_left, ==, 1); g_assert_cmpuint (output_buffer_n_bytes_left, ==, 32); g_assert_true (input_buffer_pos == input_buffer); g_assert_true (output_buffer_pos == output_buffer); gfls_iconv_free (conv); g_free (input_buffer_raw); g_free (output_buffer); } static void test_feed_discard_output (void) { GflsIconv *conv; gboolean ok; gsize input_buffer_size; gchar *input_buffer; gchar *input_buffer_pos; gsize input_buffer_n_bytes_left; GflsIconvResult result; GError *error = NULL; conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "UTF-8", "UTF-8", NULL); g_assert_true (ok); // The internal output buffer of gfls_iconv_feed_discard_output() // has a size of 1024. So to trigger the loop condition, have something // greater than that. input_buffer_size = 2000; input_buffer = g_malloc (input_buffer_size); memset (input_buffer, 'a', input_buffer_size); input_buffer_pos = input_buffer; input_buffer_n_bytes_left = input_buffer_size; result = gfls_iconv_feed_discard_output (conv, &input_buffer_pos, &input_buffer_n_bytes_left, &error); g_assert_true (result == GFLS_ICONV_RESULT_OK); g_assert_no_error (error); g_assert_cmpuint (input_buffer_n_bytes_left, ==, 0); g_assert_true (input_buffer_pos == input_buffer + 2000); gfls_iconv_free (conv); g_free (input_buffer); } static void test_feed_lossy_conversion (void) { GflsIconv *conv; gboolean ok; gsize input_buffer_size; gsize output_buffer_size; guint8 *input_buffer_raw; gchar *input_buffer; gchar *output_buffer; gchar *input_buffer_pos; gchar *output_buffer_pos; gsize input_buffer_n_bytes_left; gsize output_buffer_n_bytes_left; GflsIconvResult result; GError *error = NULL; conv = gfls_iconv_new (); ok = gfls_iconv_open (conv, "ASCII//TRANSLIT", "UTF-8", NULL); g_assert_true (ok); input_buffer_size = 2; input_buffer_raw = g_malloc (input_buffer_size); input_buffer = (gchar *) input_buffer_raw; // "é": Latin Small Letter E With Acute (U+00E9) // which is encoded in UTF-8 as 0xC3 0xA9. input_buffer_raw[0] = 195; input_buffer_raw[1] = 169; output_buffer_size = 32; output_buffer = g_malloc (output_buffer_size); input_buffer_pos = input_buffer; output_buffer_pos = output_buffer; input_buffer_n_bytes_left = input_buffer_size; output_buffer_n_bytes_left = output_buffer_size; result = gfls_iconv_feed (conv, &input_buffer_pos, &input_buffer_n_bytes_left, &output_buffer_pos, &output_buffer_n_bytes_left, &error); g_assert_true (result == GFLS_ICONV_RESULT_LOSSY_CONVERSION); g_assert_no_error (error); g_assert_cmpuint (input_buffer_n_bytes_left, ==, 0); g_assert_cmpuint (output_buffer_n_bytes_left, ==, 31); g_assert_true (input_buffer_pos == input_buffer + 2); g_assert_true (output_buffer_pos == output_buffer + 1); g_assert_cmpuint (output_buffer[0], ==, '?'); // Depends on the implementation. gfls_iconv_free (conv); g_free (input_buffer_raw); g_free (output_buffer); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/iconv/new_and_free", test_new_and_free); g_test_add_func ("/iconv/open_and_close", test_open_and_close); g_test_add_func ("/iconv/feed_ok", test_feed_ok); g_test_add_func ("/iconv/feed_output_buffer_full", test_feed_output_buffer_full); g_test_add_func ("/iconv/feed_incomplete_input", test_feed_incomplete_input); g_test_add_func ("/iconv/feed_illegal_sequence", test_feed_illegal_sequence); g_test_add_func ("/iconv/feed_discard_output", test_feed_discard_output); g_test_add_func ("/iconv/feed_lossy_conversion", test_feed_lossy_conversion); exit_status = g_test_run (); gfls_finalize (); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/test-input-stream.c000066400000000000000000000050111526404376200305770ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2024-2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include typedef struct { /* To run the async operation. */ GMainLoop *main_loop; /* To check against the result of gfls_input_stream_read_finish(): */ gsize result_size; guint result_is_truncated : 1; } TestData; static GInputStream * create_input_stream (gsize size) { gchar *str; GBytes *bytes; GInputStream *input_stream; str = g_strnfill (size, 'A'); bytes = g_bytes_new_take (str, size); input_stream = g_memory_input_stream_new_from_bytes (bytes); g_bytes_unref (bytes); return input_stream; } static void read_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { GInputStream *input_stream = G_INPUT_STREAM (source_object); TestData *data = user_data; GBytes *bytes; gboolean is_truncated = FALSE; GError *error = NULL; bytes = gfls_input_stream_read_finish (input_stream, result, &is_truncated, &error); g_assert_no_error (error); g_assert_cmpint (is_truncated, ==, data->result_is_truncated); g_assert_nonnull (bytes); g_assert_cmpint (g_bytes_get_size (bytes), ==, data->result_size); g_bytes_unref (bytes); g_main_loop_quit (data->main_loop); } static void check_read (gsize input_stream_real_size, gsize input_stream_expected_size, gsize max_size, gsize result_size, gboolean result_is_truncated) { GInputStream *input_stream; TestData data; input_stream = create_input_stream (input_stream_real_size); data.main_loop = g_main_loop_new (NULL, FALSE); data.result_size = result_size; data.result_is_truncated = result_is_truncated != FALSE; gfls_input_stream_read_async (input_stream, input_stream_expected_size, max_size, G_PRIORITY_DEFAULT, NULL, NULL, NULL, read_cb, &data); g_main_loop_run (data.main_loop); g_object_unref (input_stream); } static void test_read (void) { check_read (0, 0, 0, 0, FALSE); check_read (0, 1, 0, 0, FALSE); check_read (1, 0, 100, 1, FALSE); check_read (100, 50, 200, 100, FALSE); check_read (100, 100, 200, 100, FALSE); check_read (100, 100, 100, 100, FALSE); /* Truncated */ check_read (1, 0, 0, 0, TRUE); check_read (2, 2, 0, 0, TRUE); check_read (100, 50, 99, 99, TRUE); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/InputStream/read", test_read); exit_status = g_test_run (); gfls_finalize (); return exit_status; } test-unsaved-document-titles.c000066400000000000000000000035051526404376200326610ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/* SPDX-FileCopyrightText: 2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void test_allocate_and_release_numbers (void) { GflsUnsavedDocumentTitles *titles; gint num_a; gint num_b; gint num_c; titles = gfls_unsaved_document_titles_get_default (); num_a = gfls_unsaved_document_titles_allocate_number (titles); num_b = gfls_unsaved_document_titles_allocate_number (titles); g_assert_cmpint (num_a, ==, 1); g_assert_cmpint (num_b, ==, 2); gfls_unsaved_document_titles_release_number (titles, num_a); num_a = 0; num_c = gfls_unsaved_document_titles_allocate_number (titles); g_assert_cmpint (num_c, ==, 1); } static gchar * my_title_cb (gint num) { return g_strdup_printf ("My Dear New Document %d", num); } static void test_title (void) { GflsUnsavedDocumentTitles *titles; gchar *title_a; gchar *title_b; gchar *my_title; titles = gfls_unsaved_document_titles_new (); title_a = gfls_unsaved_document_titles_get_title (titles, 1); gfls_unsaved_document_titles_set_title_callback (titles, my_title_cb); title_b = gfls_unsaved_document_titles_get_title (titles, 1); my_title = my_title_cb (1); g_assert_cmpstr (title_b, ==, my_title); g_free (title_b); g_free (my_title); gfls_unsaved_document_titles_set_title_callback (titles, NULL); title_b = gfls_unsaved_document_titles_get_title (titles, 1); g_assert_cmpstr (title_a, ==, title_b); g_free (title_a); g_free (title_b); g_object_unref (titles); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/UnsavedDocumentTitles/allocate_and_release_numbers", test_allocate_and_release_numbers); g_test_add_func ("/UnsavedDocumentTitles/title", test_title); exit_status = g_test_run (); gfls_finalize (); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/test-utf8.c000066400000000000000000000173231526404376200270460ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2023-2024 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void check_find_very_long_line (const gchar *str, guint max_n_bytes_per_line, gint expected_found_at_pos) { const gchar *result; result = gfls_utf8_find_very_long_line (str, max_n_bytes_per_line); if (expected_found_at_pos < 0) { g_assert_null (result); } else { gint found_at_pos; g_assert_nonnull (result); found_at_pos = result - str; g_assert_cmpint (found_at_pos, ==, expected_found_at_pos); } } static void test_find_very_long_line (void) { /* Without newline chars */ check_find_very_long_line ("", 0, -1); check_find_very_long_line ("a", 0, 0); check_find_very_long_line ("", 1, -1); check_find_very_long_line ("a", 1, -1); check_find_very_long_line ("ab", 1, 0); check_find_very_long_line ("é", 1, 0); check_find_very_long_line ("é", 2, -1); /* With \n */ check_find_very_long_line ("\n\n\n", 0, -1); check_find_very_long_line ("\na\n", 0, 1); check_find_very_long_line ("\na", 0, 1); check_find_very_long_line ("a\nb\nc\n", 1, -1); check_find_very_long_line ("a\nb\nc", 1, -1); check_find_very_long_line ("a\nbc\n", 1, 2); check_find_very_long_line ("a\nbcd\n", 1, 2); check_find_very_long_line ("a\nbcd\n", 2, 2); check_find_very_long_line ("a\nbcd", 2, 2); check_find_very_long_line ("é\nSé", 2, 3); check_find_very_long_line ("é\nSé", 3, -1); check_find_very_long_line ("é\nSé\n", 3, -1); /* Quick test with \r */ check_find_very_long_line ("\r\r\r", 0, -1); check_find_very_long_line ("\n\r\n\r\n\r", 0, -1); check_find_very_long_line ("\r\n\r\n\r\n", 0, -1); check_find_very_long_line ("a\rb\nc\rd", 1, -1); check_find_very_long_line ("a\ré", 1, 2); check_find_very_long_line ("a\ré", 2, -1); } static void test_validate_empty (void) { GBytes *bytes; GflsValidatedString *result; bytes = g_bytes_new_static ("", 0); g_assert_nonnull (bytes); result = gfls_utf8_validate (bytes); g_assert_null (result); g_bytes_unref (bytes); } static void test_validate_all_valid (void) { GBytes *bytes; GflsValidatedString *result; GflsValidatedStringChunk **chunks; // 0xC3 0xA9 is "é" in UTF-8 (it takes two bytes). // Latin Small Letter E With Acute (U+00E9) bytes = g_bytes_new_static ("abc\xC3\xA9z", 6); result = gfls_utf8_validate (bytes); chunks = gfls_validated_string_get_chunks (result); g_assert_nonnull (chunks); g_assert_nonnull (chunks[0]); g_assert_null (chunks[1]); g_assert_true (gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_true (g_bytes_equal (bytes, gfls_validated_string_chunk_get_bytes (chunks[0]))); g_bytes_unref (bytes); g_object_unref (result); } static void test_validate_contains_invalid_bytes (void) { GBytes *bytes; GBytes *bytes_to_compare; GflsValidatedString *result; GflsValidatedStringChunk **chunks; // 0xFF or 0x00 are both invalid bytes. bytes = g_bytes_new_static ("\xFF\x00zz\x00", 5); result = gfls_utf8_validate (bytes); chunks = gfls_validated_string_get_chunks (result); g_assert_nonnull (chunks); g_assert_nonnull (chunks[0]); g_assert_nonnull (chunks[1]); g_assert_nonnull (chunks[2]); g_assert_null (chunks[3]); g_assert_false (gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_true (gfls_validated_string_chunk_get_valid (chunks[1])); g_assert_false (gfls_validated_string_chunk_get_valid (chunks[2])); bytes_to_compare = g_bytes_new_static ("\\FF\\00", 6); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[0]))); g_bytes_unref (bytes_to_compare); bytes_to_compare = g_bytes_new_static ("zz", 2); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[1]))); g_bytes_unref (bytes_to_compare); bytes_to_compare = g_bytes_new_static ("\\00", 3); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[2]))); g_bytes_unref (bytes_to_compare); g_bytes_unref (bytes); g_object_unref (result); } static void test_validate_ends_with_incomplete_char (void) { GBytes *bytes; GBytes *bytes_to_compare; GflsValidatedString *result; GflsValidatedStringChunk **chunks; // 0xC3 0xA9 is "é" in UTF-8 (it takes two bytes). // Latin Small Letter E With Acute (U+00E9) // End the data with only the first byte. bytes = g_bytes_new_static ("abc\xC3", 4); result = gfls_utf8_validate (bytes); chunks = gfls_validated_string_get_chunks (result); g_assert_nonnull (chunks); g_assert_nonnull (chunks[0]); g_assert_nonnull (chunks[1]); g_assert_null (chunks[2]); g_assert_true (gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_false (gfls_validated_string_chunk_get_valid (chunks[1])); bytes_to_compare = g_bytes_new_static ("abc", 3); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[0]))); g_bytes_unref (bytes_to_compare); bytes_to_compare = g_bytes_new_static ("\\C3", 3); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[1]))); g_bytes_unref (bytes_to_compare); g_bytes_unref (bytes); g_object_unref (result); } static void test_validate_contains_incomplete_char (void) { GBytes *bytes; GBytes *bytes_to_compare; GflsValidatedString *result; GflsValidatedStringChunk **chunks; // For a two-bytes UTF-8 character, refer to Wikipedia: // First code point: U+0080 // Last code point: U+07FF // Byte 1: 110xxxyy // Byte 2: 10yyzzzz // See https://en.wikipedia.org/wiki/UTF-8 // // For example 0xC3 0xA9 is "é". // Latin Small Letter E With Acute (U+00E9) // Put only the first byte, followed by: // 1. A valid byte ('z'). // 2. An invalid byte (nul). bytes = g_bytes_new_static ("ab\xC3zz\xC3\x00", 7); result = gfls_utf8_validate (bytes); chunks = gfls_validated_string_get_chunks (result); g_assert_nonnull (chunks); g_assert_nonnull (chunks[0]); g_assert_nonnull (chunks[1]); g_assert_nonnull (chunks[2]); g_assert_nonnull (chunks[3]); g_assert_null (chunks[4]); g_assert_true (gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_false (gfls_validated_string_chunk_get_valid (chunks[1])); g_assert_true (gfls_validated_string_chunk_get_valid (chunks[2])); g_assert_false (gfls_validated_string_chunk_get_valid (chunks[3])); bytes_to_compare = g_bytes_new_static ("ab", 2); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[0]))); g_bytes_unref (bytes_to_compare); bytes_to_compare = g_bytes_new_static ("\\C3", 3); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[1]))); g_bytes_unref (bytes_to_compare); bytes_to_compare = g_bytes_new_static ("zz", 2); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[2]))); g_bytes_unref (bytes_to_compare); bytes_to_compare = g_bytes_new_static ("\\C3\\00", 6); g_assert_true (g_bytes_equal (bytes_to_compare, gfls_validated_string_chunk_get_bytes (chunks[3]))); g_bytes_unref (bytes_to_compare); g_bytes_unref (bytes); g_object_unref (result); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/utf8/find_very_long_line", test_find_very_long_line); g_test_add_func ("/utf8/validate/empty", test_validate_empty); g_test_add_func ("/utf8/validate/all_valid", test_validate_all_valid); g_test_add_func ("/utf8/validate/contains_invalid_bytes", test_validate_contains_invalid_bytes); g_test_add_func ("/utf8/validate/ends_with_incomplete_char", test_validate_ends_with_incomplete_char); g_test_add_func ("/utf8/validate/contains_incomplete_char", test_validate_contains_incomplete_char); exit_status = g_test_run (); gfls_finalize (); return exit_status; } libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/test-utils.c000066400000000000000000000032041526404376200273110ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void test_bytes_to_hex_representation (void) { const guint8 bytes[4] = {0xFF, 0x01, 0x00, 0x4A}; gchar *result; result = gfls_utils_bytes_to_hex_representation (bytes, 0); g_assert_nonnull (result); g_assert_cmpstr (result, ==, ""); g_free (result); result = gfls_utils_bytes_to_hex_representation (bytes, 4); g_assert_cmpstr (result, ==, "\\FF\\01\\00\\4A"); g_free (result); } static void test_find_nearest_power_of_two (void) { g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (0), ==, 1); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (1), ==, 1); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (2), ==, 2); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (3), ==, 4); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (4), ==, 4); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (1000), ==, 1024); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (1023), ==, 1024); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (1024), ==, 1024); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (1025), ==, 2048); g_assert_cmpuint (gfls_utils_find_nearest_power_of_two (G_MAXSIZE), ==, 0); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/utils/bytes_to_hex_representation", test_bytes_to_hex_representation); g_test_add_func ("/utils/find_nearest_power_of_two", test_find_nearest_power_of_two); exit_status = g_test_run (); gfls_finalize (); return exit_status; } test-validated-string.c000066400000000000000000000224561526404376200313450ustar00rootroot00000000000000libgedit-gfls-0.5.0-8ff9380b1796aa141c07f335ac10a405f39f988f/tests/unit-tests/* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet * SPDX-License-Identifier: LGPL-3.0-or-later */ #include static void append_chunk (GflsValidatedStringBuilder *builder, gboolean valid) { GBytes *bytes; GflsValidatedStringChunk *chunk; bytes = g_bytes_new_static ("a", 1); chunk = gfls_validated_string_chunk_new (bytes); g_bytes_unref (bytes); gfls_validated_string_chunk_set_valid (chunk, valid); gfls_validated_string_builder_append_chunk (builder, chunk); gfls_validated_string_chunk_unref (chunk); } static void test_chunk_standalone (void) { GBytes *bytes; GBytes *bytes_got; GflsValidatedStringChunk *chunk; GflsValidatedStringChunk *chunk_reffed; bytes = g_bytes_new_static ("a", 1); chunk = gfls_validated_string_chunk_new (bytes); g_assert_nonnull (chunk); chunk_reffed = gfls_validated_string_chunk_ref (chunk); g_assert_true (chunk == chunk_reffed); gfls_validated_string_chunk_unref (chunk); bytes_got = gfls_validated_string_chunk_get_bytes (chunk); g_assert_true (bytes == bytes_got); gfls_validated_string_chunk_set_valid (chunk, FALSE); g_assert_false (gfls_validated_string_chunk_get_valid (chunk)); gfls_validated_string_chunk_set_valid (chunk, TRUE); g_assert_true (gfls_validated_string_chunk_get_valid (chunk)); gfls_validated_string_chunk_unref (chunk); gfls_validated_string_chunk_unref (NULL); g_bytes_unref (bytes); } static void test_zero_chunks (void) { GflsValidatedStringBuilder *builder; GflsValidatedString *validated_string; builder = gfls_validated_string_builder_new (); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); g_assert_null (validated_string); } static void test_one_chunk (void) { GflsValidatedStringBuilder *builder; GBytes *bytes; GflsValidatedStringChunk *chunk; GflsValidatedString *validated_string; GflsValidatedStringChunk **chunks; builder = gfls_validated_string_builder_new (); bytes = g_bytes_new_static ("b", 1); chunk = gfls_validated_string_chunk_new (bytes); gfls_validated_string_builder_append_chunk (builder, chunk); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); g_assert_nonnull (validated_string); chunks = gfls_validated_string_get_chunks (validated_string); g_assert_nonnull (chunks); g_assert_true (chunks[0] == chunk); g_assert_null (chunks[1]); g_bytes_unref (bytes); gfls_validated_string_chunk_unref (chunk); g_object_unref (validated_string); } static void test_several_chunks (void) { GflsValidatedStringBuilder *builder; GBytes *bytes1; GBytes *bytes2; GflsValidatedStringChunk *chunk1; GflsValidatedStringChunk *chunk2; GflsValidatedString *validated_string; GflsValidatedStringChunk **chunks; builder = gfls_validated_string_builder_new (); bytes1 = g_bytes_new_static ("c", 1); chunk1 = gfls_validated_string_chunk_new (bytes1); gfls_validated_string_builder_append_chunk (builder, chunk1); bytes2 = g_bytes_new_static ("d", 1); chunk2 = gfls_validated_string_chunk_new (bytes2); gfls_validated_string_builder_append_chunk (builder, chunk2); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); g_assert_nonnull (validated_string); chunks = gfls_validated_string_get_chunks (validated_string); g_assert_nonnull (chunks); g_assert_true (chunks[0] == chunk1); g_assert_true (chunks[1] == chunk2); g_assert_null (chunks[2]); g_bytes_unref (bytes1); g_bytes_unref (bytes2); gfls_validated_string_chunk_unref (chunk1); gfls_validated_string_chunk_unref (chunk2); g_object_unref (validated_string); } static void test_simplify_empty (void) { GflsValidatedStringBuilder *builder; GflsValidatedString *validated_string; builder = gfls_validated_string_builder_new (); gfls_validated_string_builder_simplify (builder); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); g_assert_null (validated_string); } static void check_simplify_one_chunk (gboolean valid) { GflsValidatedStringBuilder *builder; GBytes *bytes; GflsValidatedStringChunk *chunk; GflsValidatedString *validated_string; GflsValidatedStringChunk **chunks; builder = gfls_validated_string_builder_new (); bytes = g_bytes_new_static ("b", 1); chunk = gfls_validated_string_chunk_new (bytes); gfls_validated_string_chunk_set_valid (chunk, valid); gfls_validated_string_builder_append_chunk (builder, chunk); gfls_validated_string_builder_simplify (builder); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); chunks = gfls_validated_string_get_chunks (validated_string); g_assert_nonnull (chunks); g_assert_true (chunks[0] == chunk); g_assert_null (chunks[1]); g_bytes_unref (bytes); gfls_validated_string_chunk_unref (chunk); g_object_unref (validated_string); } static void test_simplify_one_chunk (void) { check_simplify_one_chunk (TRUE); check_simplify_one_chunk (FALSE); } static void test_simplify_several_chunks (void) { GflsValidatedStringBuilder *builder; GflsValidatedString *validated_string; GflsValidatedStringChunk **chunks; builder = gfls_validated_string_builder_new (); append_chunk (builder, TRUE); append_chunk (builder, TRUE); gfls_validated_string_builder_simplify (builder); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); chunks = gfls_validated_string_get_chunks (validated_string); g_assert_nonnull (chunks); g_assert_nonnull (chunks[0]); g_assert_true (gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_null (chunks[1]); g_object_unref (validated_string); builder = gfls_validated_string_builder_new (); append_chunk (builder, FALSE); append_chunk (builder, FALSE); gfls_validated_string_builder_simplify (builder); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); chunks = gfls_validated_string_get_chunks (validated_string); g_assert_nonnull (chunks); g_assert_nonnull (chunks[0]); g_assert_false (gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_null (chunks[1]); g_object_unref (validated_string); builder = gfls_validated_string_builder_new (); append_chunk (builder, TRUE); append_chunk (builder, FALSE); append_chunk (builder, TRUE); append_chunk (builder, TRUE); append_chunk (builder, TRUE); append_chunk (builder, TRUE); append_chunk (builder, FALSE); append_chunk (builder, FALSE); append_chunk (builder, FALSE); append_chunk (builder, TRUE); append_chunk (builder, TRUE); append_chunk (builder, FALSE); gfls_validated_string_builder_simplify (builder); validated_string = gfls_validated_string_builder_free_to_validated_string (builder); chunks = gfls_validated_string_get_chunks (validated_string); g_assert_nonnull (chunks); g_assert_true (chunks[0] != NULL && gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_true (chunks[1] != NULL && !gfls_validated_string_chunk_get_valid (chunks[1])); g_assert_true (chunks[2] != NULL && gfls_validated_string_chunk_get_valid (chunks[2])); g_assert_true (chunks[3] != NULL && !gfls_validated_string_chunk_get_valid (chunks[3])); g_assert_true (chunks[4] != NULL && gfls_validated_string_chunk_get_valid (chunks[4])); g_assert_true (chunks[5] != NULL && !gfls_validated_string_chunk_get_valid (chunks[5])); g_assert_null (chunks[6]); g_object_unref (validated_string); } static void test_append_validated_string (void) { GflsValidatedStringBuilder *sub_builder; GflsValidatedString *sub_validated_string; GflsValidatedStringBuilder *super_builder; GflsValidatedString *super_validated_string; GflsValidatedStringChunk **chunks; sub_builder = gfls_validated_string_builder_new (); append_chunk (sub_builder, TRUE); append_chunk (sub_builder, TRUE); append_chunk (sub_builder, FALSE); sub_validated_string = gfls_validated_string_builder_free_to_validated_string (sub_builder); super_builder = gfls_validated_string_builder_new (); gfls_validated_string_builder_append_validated_string (super_builder, sub_validated_string); g_object_unref (sub_validated_string); append_chunk (super_builder, FALSE); gfls_validated_string_builder_simplify (super_builder); super_validated_string = gfls_validated_string_builder_free_to_validated_string (super_builder); g_assert_nonnull (super_validated_string); chunks = gfls_validated_string_get_chunks (super_validated_string); g_assert_nonnull (chunks); g_assert_true (chunks[0] != NULL && gfls_validated_string_chunk_get_valid (chunks[0])); g_assert_true (chunks[1] != NULL && !gfls_validated_string_chunk_get_valid (chunks[1])); g_assert_null (chunks[2]); g_object_unref (super_validated_string); } int main (int argc, char **argv) { int exit_status; gfls_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/ValidatedString/chunk_standalone", test_chunk_standalone); g_test_add_func ("/ValidatedString/zero_chunks", test_zero_chunks); g_test_add_func ("/ValidatedString/one_chunk", test_one_chunk); g_test_add_func ("/ValidatedString/several_chunks", test_several_chunks); g_test_add_func ("/ValidatedString/simplify_empty", test_simplify_empty); g_test_add_func ("/ValidatedString/simplify_one_chunk", test_simplify_one_chunk); g_test_add_func ("/ValidatedString/simplify_several_chunks", test_simplify_several_chunks); g_test_add_func ("/ValidatedString/append_validated_string", test_append_validated_string); exit_status = g_test_run (); gfls_finalize (); return exit_status; }