pax_global_header 0000666 0000000 0000000 00000000064 15166134262 0014520 g ustar 00root root 0000000 0000000 52 comment=ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/ 0000775 0000000 0000000 00000000000 15166134262 0022422 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/LICENSES/ 0000775 0000000 0000000 00000000000 15166134262 0023627 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/LICENSES/LGPL-3.0-or-later.txt 0000664 0000000 0000000 00000016407 15166134262 0027157 0 ustar 00root root 0000000 0000000 GNU 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/NEWS 0000664 0000000 0000000 00000002371 15166134262 0023124 0 ustar 00root root 0000000 0000000 libgedit-gfls news
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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/README.md 0000664 0000000 0000000 00000000676 15166134262 0023712 0 ustar 00root root 0000000 0000000 libgedit-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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/build/ 0000775 0000000 0000000 00000000000 15166134262 0023521 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/build/.gitignore 0000664 0000000 0000000 00000000002 15166134262 0025501 0 ustar 00root root 0000000 0000000 *
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/ 0000775 0000000 0000000 00000000000 15166134262 0023352 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/file-loading.md 0000664 0000000 0000000 00000001477 15166134262 0026237 0 ustar 00root root 0000000 0000000 libgedit-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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/generic-and-extensible.md 0000664 0000000 0000000 00000001306 15166134262 0030210 0 ustar 00root root 0000000 0000000 libgedit-gfls :: generic and extensible API
===========================================
Have for Gfls a **generic** and **extensible** API.
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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/low-level-features.md 0000664 0000000 0000000 00000001743 15166134262 0027423 0 ustar 00root root 0000000 0000000 libgedit-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.
To implement
------------
Have a list of encodings.
Loading: encoding auto-detection.
Loading: check if the content is valid in a given encoding (useful if the user
explicitly asks for a certain encoding).
Loading: encoding conversion to UTF-8.
Loading: detect BOM.
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.
Further split the list of chunks to isolate very long lines (in UTF-8) into
their own chunks.
Transform a very-long-line chunk with the line split at a certain column, and
with a certain algorithm to split the line (at chars or word-chars). Adding a
boolean to tell that the very long line has been split.
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/low-level-kit.md 0000664 0000000 0000000 00000001536 15166134262 0026374 0 ustar 00root root 0000000 0000000 libgedit-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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/names.md 0000664 0000000 0000000 00000001621 15166134262 0024777 0 ustar 00root root 0000000 0000000 libgedit-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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/reference/ 0000775 0000000 0000000 00000000000 15166134262 0025310 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/reference/libgedit-gfls-docs.xml 0000664 0000000 0000000 00000005061 15166134262 0031476 0 ustar 00root root 0000000 0000000
%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
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
libgedit-gfls-sections.txt 0000664 0000000 0000000 00000006502 15166134262 0032336 0 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/reference gfls/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-bytes-region
GflsBytesRegion
GflsBytesRegionIter
gfls_bytes_region_free
gfls_bytes_region_match_bytes
gfls_bytes_region_to_string
gfls_bytes_region_get_start_iter
gfls_bytes_region_iter_is_end
gfls_bytes_region_iter_get_sub_region
gfls_bytes_region_iter_next
gfls_bytes_region_iter_free
gfls-bytes-region-builder
GflsBytesRegionBuilder
gfls_bytes_region_builder_new
gfls_bytes_region_builder_append
gfls_bytes_region_builder_get_current_size
gfls_bytes_region_builder_free
gfls-encoding-convert
gfls_encoding_try_convert
gfls_encoding_convert
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
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/reference/meson.build 0000664 0000000 0000000 00000002243 15166134262 0027453 0 ustar 00root root 0000000 0000000 subdir('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],
install: true
)
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/reference/xml/ 0000775 0000000 0000000 00000000000 15166134262 0026110 5 ustar 00root root 0000000 0000000 gtkdocentities.ent.in 0000664 0000000 0000000 00000000142 15166134262 0032163 0 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/reference/xml
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/reference/xml/meson.build 0000664 0000000 0000000 00000000640 15166134262 0030252 0 ustar 00root root 0000000 0000000 gtkdocentities_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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/docs/split-backend-frontend.md 0000664 0000000 0000000 00000001740 15166134262 0030233 0 ustar 00root root 0000000 0000000 libgedit-gfls :: split backend from frontend
============================================
To allow the possibility of a GTK 3 and GTK 4 frontends, sharing the single
codebase for the backend (based on GLib/GIO and libICU).
First idea
----------
Have two main headers, something like that:
```
#include
#include
```
Inspired by libpeas 1.x.
Second idea
-----------
- The Gfls lib contains only the backend, it must not depend on GTK.
- Implement the GTK 3 frontend in Tepl (where TeplInfoBar is directly available,
and the libgedit-gtksourceview API too).
The backend still has GtkTextView and its limitations in mind. Example:
- Instead of providing at the end a single UTF-8 string (which is not possible
in certain cases like invalid chars that need to be escaped), provide _a list_
of a data structure containing: a GBytes, boolean infos such as whether it is
valid UTF-8, whether it's a very long line that has already been split, etc.
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/ 0000775 0000000 0000000 00000000000 15166134262 0023355 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-attribute-keys.c 0000664 0000000 0000000 00000006631 15166134262 0027434 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-attribute-keys.h 0000664 0000000 0000000 00000003354 15166134262 0027440 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-bytes-region-builder.c 0000664 0000000 0000000 00000007501 15166134262 0030510 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "gfls-bytes-region-builder.h"
#include "gfls-bytes-region-private.h"
/**
* SECTION:gfls-bytes-region-builder
* @Title: GflsBytesRegionBuilder
* @Short_description: Builds #GflsBytesRegion objects
*
* Builds #GflsBytesRegion objects.
*/
struct _GflsBytesRegionBuilder
{
GArray *sub_regions; /* (element-type GflsBytesSubRegionBounds) */
gsize current_position;
};
/**
* gfls_bytes_region_builder_new: (skip)
*
* Returns: (transfer full): a new #GflsBytesRegionBuilder.
* Since: 0.4
*/
GflsBytesRegionBuilder *
gfls_bytes_region_builder_new (void)
{
GflsBytesRegionBuilder *builder;
builder = g_new0 (GflsBytesRegionBuilder, 1);
builder->sub_regions = g_array_new (FALSE, FALSE, sizeof (GflsBytesSubRegionBounds));
return builder;
}
/**
* gfls_bytes_region_builder_free: (skip)
* @builder: (nullable): a #GflsBytesRegionBuilder.
* @free_data: if %TRUE, the data is freed as well.
*
* Creates a #GflsBytesRegion and frees @builder.
*
* Returns: (transfer full) (nullable): a #GflsBytesRegion, or %NULL if
* @free_data is %TRUE.
* Since: 0.4
*/
GflsBytesRegion *
gfls_bytes_region_builder_free (GflsBytesRegionBuilder *builder,
gboolean free_data)
{
GflsBytesRegion *region = NULL;
if (builder == NULL)
{
return NULL;
}
if (!free_data)
{
region = _gfls_bytes_region_new (builder->sub_regions,
builder->current_position);
}
g_array_unref (builder->sub_regions);
g_free (builder);
return region;
}
/**
* gfls_bytes_region_builder_append:
* @builder: a #GflsBytesRegionBuilder.
* @sub_region_length: the length of the sub-region. Must not be equal to 0.
* @is_part_of_region: whether the sub-region is part of the region.
*
* Appends a sub-region at the end.
*
* If @is_part_of_region is %FALSE it creates a hole.
*
* Contiguous sub-regions of the same kind are merged and will thus be treated
* as a single sub-region. So you can conveniently call this function several
* times in a row with the same value for @is_part_of_region.
*
* In order to create a #GflsBytesRegion that will traverse a whole #GBytes, it
* is required to call this function the right amount of times, even if it ends
* with a hole. See also gfls_bytes_region_match_bytes().
*
* Since: 0.4
*/
void
gfls_bytes_region_builder_append (GflsBytesRegionBuilder *builder,
gsize sub_region_length,
gboolean is_part_of_region)
{
gsize next_position = 0;
g_return_if_fail (builder != NULL);
g_return_if_fail (sub_region_length != 0);
if (!g_size_checked_add (&next_position,
builder->current_position,
sub_region_length))
{
g_warning ("Ignoring the sub-region because of an integer overflow.");
return;
}
if (is_part_of_region)
{
GflsBytesSubRegionBounds *last_sub_region = NULL;
if (builder->sub_regions->len != 0)
{
last_sub_region = &g_array_index (builder->sub_regions,
GflsBytesSubRegionBounds,
builder->sub_regions->len - 1);
}
/* Merge */
if (last_sub_region != NULL &&
last_sub_region->end == builder->current_position)
{
last_sub_region->end = next_position;
}
/* Insert new sub-region */
else
{
GflsBytesSubRegionBounds new_sub_region;
new_sub_region.start = builder->current_position;
new_sub_region.end = next_position;
g_array_append_val (builder->sub_regions, new_sub_region);
}
}
builder->current_position = next_position;
}
/**
* gfls_bytes_region_builder_get_current_size:
* @builder: a #GflsBytesRegionBuilder.
*
* Returns: the current total size, in number of bytes (holes included).
* Since: 0.4
*/
gsize
gfls_bytes_region_builder_get_current_size (GflsBytesRegionBuilder *builder)
{
g_return_val_if_fail (builder != NULL, 0);
return builder->current_position;
}
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-bytes-region-builder.h 0000664 0000000 0000000 00000001611 15166134262 0030511 0 ustar 00root root 0000000 0000000 /* 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 _GflsBytesRegionBuilder GflsBytesRegionBuilder;
G_MODULE_EXPORT
GflsBytesRegionBuilder * gfls_bytes_region_builder_new (void);
G_MODULE_EXPORT
GflsBytesRegion * gfls_bytes_region_builder_free (GflsBytesRegionBuilder *builder,
gboolean free_data);
G_MODULE_EXPORT
void gfls_bytes_region_builder_append (GflsBytesRegionBuilder *builder,
gsize sub_region_length,
gboolean is_part_of_region);
G_MODULE_EXPORT
gsize gfls_bytes_region_builder_get_current_size (GflsBytesRegionBuilder *builder);
G_END_DECLS
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-bytes-region-private.h 0000664 0000000 0000000 00000000566 15166134262 0030545 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#pragma once
#include
#include "gfls-bytes-region.h"
G_BEGIN_DECLS
typedef struct
{
gsize start;
gsize end;
} GflsBytesSubRegionBounds;
G_GNUC_INTERNAL
GflsBytesRegion * _gfls_bytes_region_new (GArray *sub_regions,
gsize total_size);
G_END_DECLS
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-bytes-region.c 0000664 0000000 0000000 00000026242 15166134262 0027067 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "gfls-bytes-region.h"
#include "gfls-bytes-region-private.h"
/**
* SECTION:gfls-bytes-region
* @Title: GflsBytesRegion
* @Short_description: A group of sub-regions of a #GBytes
*
* #GflsBytesRegion permits to store a group of sub-regions of a #GBytes. Use a
* #GflsBytesRegionBuilder to construct a #GflsBytesRegion.
*
* Use-case: the region delimits valid (or invalid) bytes in a specified
* character encoding, possibly after a conversion (or at least a validation).
*
* To iterate through the sub-regions, you need to use a #GflsBytesRegionIter:
* |[
* GflsBytesRegion *region;
* GflsBytesRegionIter *iter;
* GBytes *bytes;
*
* if (!gfls_bytes_region_match_bytes (region, bytes))
* {
* return;
* }
*
* iter = gfls_bytes_region_get_start_iter (region);
*
* while (!gfls_bytes_region_iter_is_end (region, iter))
* {
* gsize sub_region_size = 0;
* gsize offset = 0;
* gboolean is_part_of_region = FALSE;
* gconstpointer sub_region_data;
*
* gfls_bytes_region_iter_get_sub_region (region,
* iter,
* &sub_region_size,
* &offset,
* &is_part_of_region);
*
* sub_region_data = g_bytes_get_region (bytes,
* sub_region_size,
* offset,
* 1);
*
* // Do something useful with the sub-region.
*
* gfls_bytes_region_iter_next (region, iter);
* }
*
* gfls_bytes_region_iter_free (region, iter);
* ]|
*
* This traverses the #GBytes from start to end. @is_part_of_region permits to
* know if the sub-region is part of the #GflsBytesRegion or if it is a "hole".
* (A hole doesn't mean that there are no bytes, the meaning depends on the
* use-case).
*/
struct _GflsBytesRegion
{
GArray *sub_regions; /* (element-type GflsBytesSubRegionBounds) */
gsize total_size;
};
/* Example:
* - GflsBytesRegion's @sub_regions is: [1, 3], [4, 5]
* - GflsBytesRegion's @total_size is: 6
*
* Then the GflsBytesRegionIter will go through these values:
* - { 0, TRUE } : corresponds to the [0, 1] range.
* - { 0, FALSE } : before=false which means *inside* the sub-region [1, 3].
* - { 1, TRUE } : between [1, 3] and [4, 5], so [3, 4].
* - { 1, FALSE } : [4, 5].
* - { 2, TRUE } : outside the sub_regions GArray, which means *after* the last
* sub-region, here [5, 6].
* - { 2, FALSE } : the end iterator.
*
* A GflsBytesRegionIter needs to internally skip empty ranges.
*/
struct _GflsBytesRegionIter
{
guint sub_region_index;
guint before : 1;
};
GflsBytesRegion *
_gfls_bytes_region_new (GArray *sub_regions,
gsize total_size)
{
GflsBytesRegion *region;
g_return_val_if_fail (sub_regions != NULL, NULL);
region = g_new0 (GflsBytesRegion, 1);
region->sub_regions = g_array_ref (sub_regions);
region->total_size = total_size;
return region;
}
/**
* gfls_bytes_region_free:
* @region: (nullable): a #GflsBytesRegion.
*
* Frees @region.
*
* Since: 0.4
*/
void
gfls_bytes_region_free (GflsBytesRegion *region)
{
if (region != NULL)
{
g_array_unref (region->sub_regions);
g_free (region);
}
}
/**
* gfls_bytes_region_match_bytes:
* @region: a #GflsBytesRegion.
* @bytes: a #GBytes.
*
* Returns: whether @region can be applied to @bytes (it checks the total size).
* Since: 0.4
*/
gboolean
gfls_bytes_region_match_bytes (GflsBytesRegion *region,
GBytes *bytes)
{
g_return_val_if_fail (region != NULL, FALSE);
g_return_val_if_fail (bytes != NULL, FALSE);
return region->total_size == g_bytes_get_size (bytes);
}
static gboolean
iter_validate (GflsBytesRegion *region,
GflsBytesRegionIter *iter,
gboolean treat_end_iter_as_valid)
{
gboolean valid;
g_return_val_if_fail (region != NULL, FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
valid = iter->sub_region_index <= region->sub_regions->len;
if (treat_end_iter_as_valid)
{
return valid;
}
return (valid &&
!gfls_bytes_region_iter_is_end (region, iter));
}
static GflsBytesSubRegionBounds
iter_get_sub_region_bounds (GflsBytesRegion *region,
GflsBytesRegionIter *iter)
{
GflsBytesSubRegionBounds prev_sub_region_bounds = { 0 };
GflsBytesSubRegionBounds next_sub_region_bounds = { 0 };
GflsBytesSubRegionBounds ret = { 0 };
g_return_val_if_fail (iter_validate (region, iter, FALSE), ret);
/* _Inside_ a sub-region (the easy case) */
if (!iter->before)
{
return g_array_index (region->sub_regions,
GflsBytesSubRegionBounds,
iter->sub_region_index);
}
/* _Outside_ a sub-region */
// Get prev_sub_region_bounds
if (iter->sub_region_index == 0)
{
prev_sub_region_bounds.start = 0;
prev_sub_region_bounds.end = 0;
}
else
{
prev_sub_region_bounds = g_array_index (region->sub_regions,
GflsBytesSubRegionBounds,
iter->sub_region_index - 1);
}
// Get next_sub_region_bounds
if (iter->sub_region_index < region->sub_regions->len)
{
next_sub_region_bounds = g_array_index (region->sub_regions,
GflsBytesSubRegionBounds,
iter->sub_region_index);
}
else
{
next_sub_region_bounds.start = region->total_size;
next_sub_region_bounds.end = region->total_size;
}
// Return value
ret.start = prev_sub_region_bounds.end;
ret.end = next_sub_region_bounds.start;
return ret;
}
static gboolean
iter_sub_region_is_empty (GflsBytesRegion *region,
GflsBytesRegionIter *iter)
{
gsize sub_region_size = 0;
gsize offset = 0;
gboolean is_part_of_region = FALSE;
gfls_bytes_region_iter_get_sub_region (region,
iter,
&sub_region_size,
&offset,
&is_part_of_region);
return sub_region_size == 0;
}
/* "Simple", i.e. without skipping empty sub-regions. */
static void
iter_next_simple (GflsBytesRegion *region,
GflsBytesRegionIter *iter)
{
if (gfls_bytes_region_iter_is_end (region, iter))
{
/* NOP */
return;
}
if (iter->before)
{
iter->before = FALSE;
}
else
{
iter->before = TRUE;
iter->sub_region_index++;
}
}
static void
iter_skip_empty_sub_regions (GflsBytesRegion *region,
GflsBytesRegionIter *iter)
{
while (!gfls_bytes_region_iter_is_end (region, iter) &&
iter_sub_region_is_empty (region, iter))
{
iter_next_simple (region, iter);
}
}
/**
* gfls_bytes_region_get_start_iter: (skip)
* @region: a #GflsBytesRegion.
*
* Returns: (transfer full): a new #GflsBytesRegionIter located at the
* beginning. Free with gfls_bytes_region_iter_free().
* Since: 0.4
*/
GflsBytesRegionIter *
gfls_bytes_region_get_start_iter (GflsBytesRegion *region)
{
GflsBytesRegionIter *iter;
g_return_val_if_fail (region != NULL, NULL);
iter = g_new0 (GflsBytesRegionIter, 1);
iter->sub_region_index = 0;
iter->before = TRUE;
iter_skip_empty_sub_regions (region, iter);
return iter;
}
/**
* gfls_bytes_region_iter_free:
* @region: a #GflsBytesRegion.
* @iter: (nullable): a #GflsBytesRegionIter.
*
* Frees @iter.
*
* Since: 0.4
*/
void
gfls_bytes_region_iter_free (GflsBytesRegion *region,
GflsBytesRegionIter *iter)
{
g_free (iter);
}
/**
* gfls_bytes_region_iter_is_end:
* @region: a #GflsBytesRegion.
* @iter: a #GflsBytesRegionIter.
*
* Returns: whether @iter is the end iterator.
* Since: 0.4
*/
gboolean
gfls_bytes_region_iter_is_end (GflsBytesRegion *region,
GflsBytesRegionIter *iter)
{
g_return_val_if_fail (region != NULL, FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
return (!iter->before &&
iter->sub_region_index == region->sub_regions->len);
}
/**
* gfls_bytes_region_iter_get_sub_region:
* @region: a #GflsBytesRegion.
* @iter: a #GflsBytesRegionIter. It must not be the end iterator.
* @sub_region_size: (out) (not nullable): the sub-region size.
* @offset: (out) (not nullable): the offset to the start of the sub-region.
* @is_part_of_region: (out) (not nullable): whether the sub-region is part of the region.
*
* Gets the sub-region at this iterator.
*
* @sub_region_size and @offset can be used as arguments to
* g_bytes_get_region().
*
* @is_part_of_region has the same meaning as for
* gfls_bytes_region_builder_append(). #GflsBytesRegionIter iterates on both the
* region and the holes, so that the corresponding #GBytes is traversed from
* start to end.
*
* Since: 0.4
*/
void
gfls_bytes_region_iter_get_sub_region (GflsBytesRegion *region,
GflsBytesRegionIter *iter,
gsize *sub_region_size,
gsize *offset,
gboolean *is_part_of_region)
{
GflsBytesSubRegionBounds sub_region_bounds;
if (sub_region_size != NULL)
{
*sub_region_size = 0;
}
if (offset != NULL)
{
*offset = 0;
}
if (is_part_of_region != NULL)
{
*is_part_of_region = FALSE;
}
g_return_if_fail (region != NULL);
g_return_if_fail (iter != NULL);
g_return_if_fail (iter_validate (region, iter, FALSE));
g_return_if_fail (sub_region_size != NULL);
g_return_if_fail (offset != NULL);
g_return_if_fail (is_part_of_region != NULL);
sub_region_bounds = iter_get_sub_region_bounds (region, iter);
g_return_if_fail (sub_region_bounds.end >= sub_region_bounds.start);
*sub_region_size = sub_region_bounds.end - sub_region_bounds.start;
*offset = sub_region_bounds.start;
*is_part_of_region = !iter->before;
}
/**
* gfls_bytes_region_iter_next:
* @region: a #GflsBytesRegion.
* @iter: a #GflsBytesRegionIter. The end iterator is accepted as an input
* value.
*
* Moves @iter to the next sub-region.
*
* If all sub-regions have been traversed, @iter is set to the end iterator.
*
* Since: 0.4
*/
void
gfls_bytes_region_iter_next (GflsBytesRegion *region,
GflsBytesRegionIter *iter)
{
g_return_if_fail (region != NULL);
g_return_if_fail (iter != NULL);
g_return_if_fail (iter_validate (region, iter, TRUE));
iter_next_simple (region, iter);
iter_skip_empty_sub_regions (region, iter);
}
/**
* gfls_bytes_region_to_string:
* @region: a #GflsBytesRegion.
*
* The format is:
*
* `[offset, sub_region_size, is_part_of_region]\n`
*
* One line per sub-region, in order.
*
* Returns: (transfer full): a string representation of @region.
* Since: 0.4
*/
gchar *
gfls_bytes_region_to_string (GflsBytesRegion *region)
{
GString *string;
GflsBytesRegionIter *iter;
g_return_val_if_fail (region != NULL, NULL);
string = g_string_new (NULL);
iter = gfls_bytes_region_get_start_iter (region);
while (!gfls_bytes_region_iter_is_end (region, iter))
{
gsize sub_region_size = 0;
gsize offset = 0;
gboolean is_part_of_region = FALSE;
gfls_bytes_region_iter_get_sub_region (region,
iter,
&sub_region_size,
&offset,
&is_part_of_region);
g_string_append_printf (string,
"[%" G_GSIZE_FORMAT ", %" G_GSIZE_FORMAT ", %d]\n",
offset,
sub_region_size,
is_part_of_region);
gfls_bytes_region_iter_next (region, iter);
}
gfls_bytes_region_iter_free (region, iter);
return g_string_free (string, FALSE);
}
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-bytes-region.h 0000664 0000000 0000000 00000002573 15166134262 0027075 0 ustar 00root root 0000000 0000000 /* 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 _GflsBytesRegion GflsBytesRegion;
typedef struct _GflsBytesRegionIter GflsBytesRegionIter;
G_MODULE_EXPORT
void gfls_bytes_region_free (GflsBytesRegion *region);
G_MODULE_EXPORT
gboolean gfls_bytes_region_match_bytes (GflsBytesRegion *region,
GBytes *bytes);
G_MODULE_EXPORT
gchar * gfls_bytes_region_to_string (GflsBytesRegion *region);
G_MODULE_EXPORT
GflsBytesRegionIter * gfls_bytes_region_get_start_iter (GflsBytesRegion *region);
G_MODULE_EXPORT
void gfls_bytes_region_iter_free (GflsBytesRegion *region,
GflsBytesRegionIter *iter);
G_MODULE_EXPORT
gboolean gfls_bytes_region_iter_is_end (GflsBytesRegion *region,
GflsBytesRegionIter *iter);
G_MODULE_EXPORT
void gfls_bytes_region_iter_get_sub_region (GflsBytesRegion *region,
GflsBytesRegionIter *iter,
gsize *sub_region_size,
gsize *offset,
gboolean *is_part_of_region);
G_MODULE_EXPORT
void gfls_bytes_region_iter_next (GflsBytesRegion *region,
GflsBytesRegionIter *iter);
G_END_DECLS
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-encoding-conversion.c 0000664 0000000 0000000 00000004322 15166134262 0030424 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2025-2026 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "gfls-encoding-conversion.h"
#include "gfls-iconv.h"
/**
* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-encoding-conversion.h 0000664 0000000 0000000 00000000715 15166134262 0030433 0 ustar 00root root 0000000 0000000 /* 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
G_BEGIN_DECLS
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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-encoding-convert.c 0000664 0000000 0000000 00000040504 15166134262 0027721 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "gfls-config.h"
#include "gfls-encoding-convert.h"
#include
#include "gfls-bytes-region-builder.h"
#include "gfls-iconv.h"
/**
* SECTION:gfls-encoding-convert
* @Title: GflsEncodingConvert
* @Short_description: Character encoding conversion
*
* Functions used for character encoding conversion.
*/
/* # Use-case
*
* The gfls_encoding_convert() function has been designed for loading a file
* into a #GtkTextBuffer scenario. Regarding the performances, the insertions in
* the #GtkTextBuffer are the slow part, so there must be as few insertions as
* possible.
*
* In other words, if there are no invalid chars and the target encoding is
* UTF-8, have as a result a single UTF-8 string that can be inserted at once.
*
* # Output format
*
* For the output format, a previous implementation created a list of "Chunk"
* structs containing two fields: a #GBytes for the data, and a boolean for
* whether it's valid/invalid. But it consumed more memory.
*
* A worst case scenario is when there are lots of interleavings of
* valid/invalid chunks.
*
* The current output format with a #GBytes combined with a #GflsBytesRegion
* is normally more memory efficient.
*
* # Implementation notes about memory allocations
*
* Since we don't know how big the output will be, memory reallocations are
* necessary. So use g_malloc() and g_realloc() family of functions. At the end,
* there is the need to realloc at the right size, to not consume more memory
* than necessary.
*/
/* 8 KiB */
#define OUTPUT_BUFFER_STEP_SIZE (8192)
/* Invariants:
* - 0 <= (@position - @data) <= @size
* - @n_bytes_left <= @size
* - @n_bytes_left == @size - (@position - @data)
*
* It would be possible to remove one field because there are some redundancies.
* But the code is probably easier if the redundancy is kept.
*/
typedef struct
{
/* Points to the beginning of the buffer data.
* Can be owned or unowned.
*/
gchar *data;
/* Points to the current position in @data.
* Always unowned.
*/
gchar *position;
/* The total size of the memory allocation of @data. */
gsize size;
/* The number of bytes not yet written in @data, starting at @position. */
gsize n_bytes_left;
} Buffer;
typedef struct
{
GflsIconv *conv;
/* The @data field is unowned. */
Buffer input_buffer;
/* The @data field is owned. */
Buffer output_buffer;
GflsBytesRegionBuilder *output_bytes_valid_region_builder;
guint allow_invalid_characters : 1;
} Converter;
static gboolean
check_buffer_invariants (Buffer *buffer)
{
gintptr n_bytes_written;
n_bytes_written = buffer->position - buffer->data;
g_return_val_if_fail (n_bytes_written >= 0, FALSE);
g_return_val_if_fail (n_bytes_written <= (gintptr)buffer->size, FALSE);
g_return_val_if_fail (buffer->n_bytes_left <= buffer->size, FALSE);
g_return_val_if_fail (buffer->n_bytes_left == buffer->size - n_bytes_written, FALSE);
return TRUE;
}
static gboolean
check_class_invariants (Converter *conv)
{
g_return_val_if_fail (check_buffer_invariants (&conv->input_buffer), FALSE);
g_return_val_if_fail (check_buffer_invariants (&conv->output_buffer), FALSE);
if (conv->output_bytes_valid_region_builder == NULL)
{
g_return_val_if_fail (conv->output_buffer.data == NULL, FALSE);
}
else
{
gsize n_bytes_written1;
gsize n_bytes_written2;
gsize n_bytes_written3;
g_return_val_if_fail (conv->output_buffer.data != NULL, FALSE);
/* There are multiple ways to know the number of bytes written. */
n_bytes_written1 = gfls_bytes_region_builder_get_current_size (conv->output_bytes_valid_region_builder);
n_bytes_written2 = conv->output_buffer.size - conv->output_buffer.n_bytes_left;
n_bytes_written3 = conv->output_buffer.position - conv->output_buffer.data;
g_return_val_if_fail (n_bytes_written1 == n_bytes_written2, FALSE);
g_return_val_if_fail (n_bytes_written1 == n_bytes_written3, FALSE);
}
return TRUE;
}
static void
converter_init (Converter *conv,
GBytes *input_bytes,
gboolean allow_invalid_characters)
{
conv->conv = gfls_iconv_new ();
conv->input_buffer.data = (gchar *) g_bytes_get_data (input_bytes, NULL);
conv->input_buffer.position = conv->input_buffer.data;
conv->input_buffer.size = g_bytes_get_size (input_bytes);
conv->input_buffer.n_bytes_left = conv->input_buffer.size;
conv->allow_invalid_characters = allow_invalid_characters != FALSE;
g_return_if_fail (check_class_invariants (conv));
/* The output is lazily initialized, see init_output(). */
}
static void
init_output (Converter *conv)
{
if (conv->output_bytes_valid_region_builder != NULL)
{
return;
}
conv->output_bytes_valid_region_builder = gfls_bytes_region_builder_new ();
/* Allocate the same size as the input + some margin, to hopefully
* reduce the number of re-allocations.
*/
if (!g_size_checked_add (&conv->output_buffer.size,
conv->input_buffer.size,
OUTPUT_BUFFER_STEP_SIZE))
{
g_assert_not_reached ();
}
/* Use g_malloc0(), more secure than g_malloc(). */
conv->output_buffer.data = g_malloc0 (conv->output_buffer.size);
conv->output_buffer.position = conv->output_buffer.data;
conv->output_buffer.n_bytes_left = conv->output_buffer.size;
}
static void
enlarge_output_buffer (Converter *conv,
gsize n_additional_bytes_needed)
{
gsize n_additional_bytes;
gsize new_size;
gsize n_bytes_written;
g_return_if_fail (conv->output_buffer.data != NULL);
n_additional_bytes = MAX (n_additional_bytes_needed, OUTPUT_BUFFER_STEP_SIZE);
if (!g_size_checked_add (&new_size,
conv->output_buffer.size,
n_additional_bytes))
{
g_assert_not_reached ();
}
n_bytes_written = conv->output_buffer.position - conv->output_buffer.data;
conv->output_buffer.data = g_realloc (conv->output_buffer.data, new_size);
conv->output_buffer.position = conv->output_buffer.data + n_bytes_written;
conv->output_buffer.size = new_size;
conv->output_buffer.n_bytes_left += n_additional_bytes;
/* Fill the new chunk with 0's. */
memset (conv->output_buffer.data + new_size - n_additional_bytes,
0,
n_additional_bytes);
}
static void
free_output (Converter *conv)
{
g_free (conv->output_buffer.data);
conv->output_buffer.data = NULL;
conv->output_buffer.position = NULL;
conv->output_buffer.size = 0;
conv->output_buffer.n_bytes_left = 0;
gfls_bytes_region_builder_free (conv->output_bytes_valid_region_builder, TRUE);
conv->output_bytes_valid_region_builder = NULL;
}
static void
converter_finalize (Converter *conv)
{
gfls_iconv_free (conv->conv);
free_output (conv);
}
static void
append_valid_sub_region (Converter *conv)
{
gsize n_bytes_written_before;
gsize n_bytes_written_after;
gsize sub_region_length;
n_bytes_written_before = gfls_bytes_region_builder_get_current_size (conv->output_bytes_valid_region_builder);
n_bytes_written_after = conv->output_buffer.position - conv->output_buffer.data;
g_return_if_fail (n_bytes_written_before <= n_bytes_written_after);
sub_region_length = n_bytes_written_after - n_bytes_written_before;
if (sub_region_length != 0)
{
gfls_bytes_region_builder_append (conv->output_bytes_valid_region_builder,
sub_region_length,
TRUE);
}
}
static void
handle_iconv_result_ok (Converter *conv)
{
g_warn_if_fail (conv->input_buffer.n_bytes_left == 0);
append_valid_sub_region (conv);
}
static void
handle_iconv_result_error (Converter *conv)
{
free_output (conv);
}
static void
handle_iconv_result_illegal_sequence (Converter *conv)
{
g_return_if_fail (conv->input_buffer.n_bytes_left > 0);
g_return_if_fail (conv->allow_invalid_characters);
/* First chunk: what has been converted successfully. */
append_valid_sub_region (conv);
/* Second chunk: the invalid byte from the input buffer. */
if (conv->output_buffer.n_bytes_left == 0)
{
enlarge_output_buffer (conv, 1);
}
*conv->output_buffer.position = *conv->input_buffer.position;
conv->input_buffer.position++;
conv->input_buffer.n_bytes_left--;
conv->output_buffer.position++;
conv->output_buffer.n_bytes_left--;
gfls_bytes_region_builder_append (conv->output_bytes_valid_region_builder, 1, FALSE);
}
static void
handle_iconv_result_incomplete_input (Converter *conv)
{
g_return_if_fail (conv->input_buffer.n_bytes_left > 0);
g_return_if_fail (conv->allow_invalid_characters);
/* First chunk: what has been converted successfully. */
append_valid_sub_region (conv);
/* Second chunk: the remained bytes from the input buffer. */
if (conv->output_buffer.n_bytes_left < conv->input_buffer.n_bytes_left)
{
enlarge_output_buffer (conv, conv->input_buffer.n_bytes_left - conv->output_buffer.n_bytes_left);
}
memcpy (conv->output_buffer.position,
conv->input_buffer.position,
conv->input_buffer.n_bytes_left);
gfls_bytes_region_builder_append (conv->output_bytes_valid_region_builder,
conv->input_buffer.n_bytes_left,
FALSE);
conv->input_buffer.position += conv->input_buffer.n_bytes_left;
conv->output_buffer.position += conv->input_buffer.n_bytes_left;
conv->output_buffer.n_bytes_left -= conv->input_buffer.n_bytes_left;
conv->input_buffer.n_bytes_left = 0;
}
static void
handle_iconv_result_output_buffer_full (Converter *conv)
{
append_valid_sub_region (conv);
enlarge_output_buffer (conv, OUTPUT_BUFFER_STEP_SIZE);
}
static void
handle_iconv_result_lossy_conversion (Converter *conv,
GError **error)
{
g_set_error (error,
G_CONVERT_ERROR,
G_CONVERT_ERROR_FAILED,
_("A number of nonreversible conversions have been performed."));
handle_iconv_result_error (conv);
}
static void
handle_invalid_character_encountered (Converter *conv,
GError **error)
{
g_return_if_fail (!conv->allow_invalid_characters);
g_set_error (error,
G_CONVERT_ERROR,
G_CONVERT_ERROR_FAILED,
_("An invalid character has been encountered."));
handle_iconv_result_error (conv);
}
static gboolean
convert (Converter *conv,
GError **error)
{
gboolean success = TRUE;
init_output (conv);
while (conv->input_buffer.n_bytes_left > 0)
{
GflsIconvResult conv_result;
g_return_val_if_fail (check_class_invariants (conv), FALSE);
conv_result = gfls_iconv_feed (conv->conv,
&conv->input_buffer.position, &conv->input_buffer.n_bytes_left,
&conv->output_buffer.position, &conv->output_buffer.n_bytes_left,
error);
if (conv_result == GFLS_ICONV_RESULT_OK)
{
handle_iconv_result_ok (conv);
break;
}
else if (conv_result == GFLS_ICONV_RESULT_ERROR)
{
handle_iconv_result_error (conv);
success = FALSE;
break;
}
else if (conv_result == GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE)
{
if (conv->allow_invalid_characters)
{
handle_iconv_result_illegal_sequence (conv);
continue;
}
else
{
handle_invalid_character_encountered (conv, error);
success = FALSE;
break;
}
}
else if (conv_result == GFLS_ICONV_RESULT_INCOMPLETE_INPUT)
{
if (conv->allow_invalid_characters)
{
handle_iconv_result_incomplete_input (conv);
break;
}
else
{
handle_invalid_character_encountered (conv, error);
success = FALSE;
break;
}
}
else if (conv_result == GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL)
{
handle_iconv_result_output_buffer_full (conv);
continue;
}
else if (conv_result == GFLS_ICONV_RESULT_LOSSY_CONVERSION)
{
handle_iconv_result_lossy_conversion (conv, error);
success = FALSE;
break;
}
}
g_return_val_if_fail (check_class_invariants (conv), FALSE);
return success;
}
static gboolean
finish_convert (Converter *conv,
GError **error)
{
GflsIconvResult conv_result;
gboolean success = TRUE;
conv->input_buffer.data = NULL;
conv->input_buffer.position = NULL;
conv->input_buffer.size = 0;
conv->input_buffer.n_bytes_left = 0;
if (conv->output_buffer.n_bytes_left < OUTPUT_BUFFER_STEP_SIZE)
{
enlarge_output_buffer (conv, OUTPUT_BUFFER_STEP_SIZE - conv->output_buffer.n_bytes_left);
}
g_return_val_if_fail (check_class_invariants (conv), FALSE);
/* Do not call it in a loop because the output_buffer should be big
* enough.
*/
conv_result = gfls_iconv_feed (conv->conv,
NULL, NULL,
&conv->output_buffer.position, &conv->output_buffer.n_bytes_left,
error);
if (conv_result == GFLS_ICONV_RESULT_OK)
{
handle_iconv_result_ok (conv);
}
else if (conv_result == GFLS_ICONV_RESULT_ERROR)
{
handle_iconv_result_error (conv);
success = FALSE;
}
else if (conv_result == GFLS_ICONV_RESULT_ILLEGAL_SEQUENCE ||
conv_result == GFLS_ICONV_RESULT_INCOMPLETE_INPUT ||
conv_result == GFLS_ICONV_RESULT_OUTPUT_BUFFER_FULL)
{
/* Unexpected */
g_warn_if_reached ();
handle_iconv_result_error (conv);
success = FALSE;
}
else if (conv_result == GFLS_ICONV_RESULT_LOSSY_CONVERSION)
{
handle_iconv_result_lossy_conversion (conv, error);
success = FALSE;
}
g_return_val_if_fail (check_class_invariants (conv), FALSE);
return success;
}
/**
* gfls_encoding_convert:
* @input_bytes: the input #GBytes to convert.
* @to_codeset: destination codeset.
* @from_codeset: source codeset.
* @allow_invalid_characters: whether invalid characters are allowed.
* @output_bytes: (out) (transfer full): the output #GBytes. It must initially
* point to a %NULL #GBytes value.
* @output_bytes_valid_region: (out) (transfer full): the output
* #GflsBytesRegion that represents the valid characters. It must initially
* point to a %NULL #GflsBytesRegion value.
* @error: location to a %NULL #GError, or %NULL.
*
* This function converts @input_bytes from a codeset to another.
*
* @from_codeset and @to_codeset must be compatible with iconv, see
* gfls_iconv_open().
*
* Note that @from_codeset and @to_codeset can be equal. It is useful to
* identify the valid characters from the invalid ones.
*
* The output is the combination of @output_bytes and
* @output_bytes_valid_region. Output bytes that are part of
* @output_bytes_valid_region are the valid characters (successfully converted).
* The other output bytes are invalid characters (copied as is from
* @input_bytes).
*
* If @allow_invalid_characters is %FALSE:
* - As soon as an invalid character is encountered, %FALSE is returned by this
* function and @output_bytes and @output_bytes_valid_region will return
* %NULL.
* - Otherwise, if everything goes well, %TRUE is returned alongside the
* @output_bytes and @output_bytes_valid_region (the latter contains in this
* case only one, valid sub-region).
*
* Returns: %TRUE on success, %FALSE otherwise.
* Since: 0.4
*/
gboolean
gfls_encoding_convert (GBytes *input_bytes,
const gchar *to_codeset,
const gchar *from_codeset,
gboolean allow_invalid_characters,
GBytes **output_bytes,
GflsBytesRegion **output_bytes_valid_region,
GError **error)
{
Converter *conv;
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);
g_return_val_if_fail (output_bytes != NULL && *output_bytes == NULL, FALSE);
g_return_val_if_fail (output_bytes_valid_region != NULL && *output_bytes_valid_region == NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
conv = g_alloca0 (sizeof (Converter));
converter_init (conv, input_bytes, allow_invalid_characters);
if (!gfls_iconv_open (conv->conv, to_codeset, from_codeset, error))
{
goto out;
}
if (!convert (conv, error))
{
goto out;
}
if (!finish_convert (conv, error))
{
goto out;
}
if (!gfls_iconv_close (conv->conv, error))
{
goto out;
}
if (!check_class_invariants (conv))
{
goto out;
}
/* Success */
if (conv->output_bytes_valid_region_builder != NULL)
{
gsize final_size;
gchar *output_data;
final_size = gfls_bytes_region_builder_get_current_size (conv->output_bytes_valid_region_builder);
output_data = g_realloc (conv->output_buffer.data, final_size);
conv->output_buffer.data = NULL;
conv->output_buffer.position = NULL;
conv->output_buffer.size = 0;
conv->output_buffer.n_bytes_left = 0;
*output_bytes = g_bytes_new_take (output_data, final_size);
output_data = NULL;
*output_bytes_valid_region = gfls_bytes_region_builder_free (conv->output_bytes_valid_region_builder, FALSE);
conv->output_bytes_valid_region_builder = NULL;
success = TRUE;
}
out:
converter_finalize (conv);
return success;
}
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-encoding-convert.h 0000664 0000000 0000000 00000001174 15166134262 0027726 0 ustar 00root root 0000000 0000000 /* 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
gboolean gfls_encoding_convert (GBytes *input_bytes,
const gchar *to_codeset,
const gchar *from_codeset,
gboolean allow_invalid_characters,
GBytes **output_bytes,
GflsBytesRegion **output_bytes_valid_region,
GError **error);
G_END_DECLS
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-error.c 0000664 0000000 0000000 00000002171 15166134262 0025604 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-error.h 0000664 0000000 0000000 00000002402 15166134262 0025606 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-iconv.c 0000664 0000000 0000000 00000022265 15166134262 0025577 0 ustar 00root root 0000000 0000000 /* 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.
*
* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-iconv.h 0000664 0000000 0000000 00000004276 15166134262 0025606 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-init.c 0000664 0000000 0000000 00000002462 15166134262 0025421 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-init.h 0000664 0000000 0000000 00000000651 15166134262 0025424 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-input-stream.c 0000664 0000000 0000000 00000027167 15166134262 0027117 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-input-stream.h 0000664 0000000 0000000 00000002305 15166134262 0027107 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-loader-basic.c 0000664 0000000 0000000 00000021165 15166134262 0027004 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-loader-basic.h 0000664 0000000 0000000 00000001477 15166134262 0027015 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-loader-config-simple.c 0000664 0000000 0000000 00000006005 15166134262 0030453 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-loader-config-simple.h 0000664 0000000 0000000 00000004006 15166134262 0030457 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-loader-config.c 0000664 0000000 0000000 00000001125 15166134262 0027162 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-loader-config.h 0000664 0000000 0000000 00000002267 15166134262 0027177 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-unsaved-document-titles.c 0000664 0000000 0000000 00000015035 15166134262 0031241 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-unsaved-document-titles.h 0000664 0000000 0000000 00000005604 15166134262 0031247 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-utf8.c 0000664 0000000 0000000 00000002541 15166134262 0025342 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2023-2024 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "gfls-utf8.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;
}
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls-utf8.h 0000664 0000000 0000000 00000000725 15166134262 0025351 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2023-2024 - 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_END_DECLS
#endif /* GFLS_UTF8_H */
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/gfls.h 0000664 0000000 0000000 00000001363 15166134262 0024464 0 ustar 00root root 0000000 0000000 /* 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
#undef GFLS_H_INSIDE
#endif /* GFLS_H */
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/meson.build 0000664 0000000 0000000 00000006343 15166134262 0025525 0 ustar 00root root 0000000 0000000 gfls_public_headers = [
'gfls.h',
'gfls-attribute-keys.h',
'gfls-bytes-region-builder.h',
'gfls-bytes-region.h',
'gfls-encoding-conversion.h',
'gfls-encoding-convert.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.h',
]
gfls_public_c_files = [
'gfls-attribute-keys.c',
'gfls-bytes-region-builder.c',
'gfls-bytes-region.c',
'gfls-encoding-conversion.c',
'gfls-encoding-convert.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.c',
]
GFLS_PRIVATE_HEADERS = [
'gfls-bytes-region-private.h',
]
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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/gfls/symbol.map 0000664 0000000 0000000 00000000043 15166134262 0025356 0 ustar 00root root 0000000 0000000 {
global:
gfls_*;
local:
*;
};
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/libgedit-gfls.doap 0000664 0000000 0000000 00000002103 15166134262 0025777 0 ustar 00root root 0000000 0000000
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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/meson.build 0000664 0000000 0000000 00000006342 15166134262 0024571 0 ustar 00root root 0000000 0000000 # 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.4.1',
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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/meson_options.txt 0000664 0000000 0000000 00000000605 15166134262 0026060 0 ustar 00root root 0000000 0000000 option(
'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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/ 0000775 0000000 0000000 00000000000 15166134262 0023040 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/LINGUAS 0000664 0000000 0000000 00000000222 15166134262 0024061 0 ustar 00root root 0000000 0000000 # Set of available languages.
# Please keep this list sorted alphabetically.
be
bg
cs
da
de
el
eu
hu
ka
kk
kw
lt
pl
pt_BR
ru
sl
sr
sv
tr
uk
zh_CN
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/POTFILES.in 0000664 0000000 0000000 00000000641 15166134262 0024616 0 ustar 00root root 0000000 0000000 # List of source files containing translatable strings.
gfls/gfls-attribute-keys.c
gfls/gfls-bytes-region-builder.c
gfls/gfls-bytes-region.c
gfls/gfls-encoding-conversion.c
gfls/gfls-encoding-convert.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.c
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/POTFILES.skip 0000664 0000000 0000000 00000000000 15166134262 0025143 0 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/be.po 0000664 0000000 0000000 00000003050 15166134262 0023764 0 ustar 00root root 0000000 0000000 # 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.6\n"
#: 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-unsaved-document-titles.c:61
#, c-format
msgid "Unsaved Document %d"
msgstr "Незахаваны дакумент %d"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/bg.po 0000664 0000000 0000000 00000003011 15166134262 0023763 0 ustar 00root root 0000000 0000000 # Bulgarian 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.
# twlvnn kraftwerk , 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-08-10 21:54+0000\n"
"PO-Revision-Date: 2025-08-23 16:07+0200\n"
"Last-Translator: twlvnn kraftwerk \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"
"X-Generator: Gtranslator 48.0\n"
#: 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-unsaved-document-titles.c:61
#, c-format
msgid "Unsaved Document %d"
msgstr "Незапазен документ %d"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/cs.po 0000664 0000000 0000000 00000002500 15166134262 0024002 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/da.po 0000664 0000000 0000000 00000004101 15166134262 0023760 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/de.po 0000664 0000000 0000000 00000002563 15166134262 0023776 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/el.po 0000664 0000000 0000000 00000003017 15166134262 0024001 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/eu.po 0000664 0000000 0000000 00000002371 15166134262 0024014 0 ustar 00root root 0000000 0000000 # 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.
# FIRST AUTHOR , YEAR.
#
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-05-10 20:14+0000\n"
"PO-Revision-Date: 2025-05-10 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-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-unsaved-document-titles.c:61
#, c-format
msgid "Unsaved Document %d"
msgstr "Gorde gabeko %d dokumentua"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/hu.po 0000664 0000000 0000000 00000004150 15166134262 0024014 0 ustar 00root root 0000000 0000000 # 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-03-09 14:04+0000\n"
"PO-Revision-Date: 2026-03-11 00:09+0100\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.08.1\n"
#: 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:138
#, 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:147
#, 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:217
#, c-format
msgid "Error during character set conversion: %s"
msgstr "Hiba a karakterkészlet-átalakítás során: %s"
#: gfls/gfls-iconv.c:309
#, 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/ka.po 0000664 0000000 0000000 00000013234 15166134262 0023776 0 ustar 00root root 0000000 0000000 # 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-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-01-13 02:09+0000\n"
"PO-Revision-Date: 2025-01-21 04:42+0100\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.5\n"
#. Translators: the first %s is a category, the second %s is the
#. * name.
#.
#: gfls/gfls-encoding.c:203
#, c-format
msgid "%s (%s)"
msgstr "%s (%s)"
#. UTF-8 first, so that it's the first encoding returned by
#. * tepl_encoding_iconv_get_all().
#.
#: gfls/gfls-encoding-manager-iconv.c:44 gfls/gfls-encoding-manager-iconv.c:61
#: gfls/gfls-encoding-manager-iconv.c:62 gfls/gfls-encoding-manager-iconv.c:63
#: gfls/gfls-encoding-manager-iconv.c:64 gfls/gfls-encoding-manager-iconv.c:65
#: gfls/gfls-encoding-manager-iconv.c:66 gfls/gfls-encoding-manager-iconv.c:67
msgid "Unicode"
msgstr "უნიკოდი"
#. FIXME GEOSTD8 ?
#: gfls/gfls-encoding-manager-iconv.c:46 gfls/gfls-encoding-manager-iconv.c:58
#: gfls/gfls-encoding-manager-iconv.c:86 gfls/gfls-encoding-manager-iconv.c:109
msgid "Western"
msgstr "დასავლური"
#: gfls/gfls-encoding-manager-iconv.c:47 gfls/gfls-encoding-manager-iconv.c:87
#: gfls/gfls-encoding-manager-iconv.c:107
msgid "Central European"
msgstr "ცენტრალურ ევროპული"
#: gfls/gfls-encoding-manager-iconv.c:48
msgid "South European"
msgstr "სამხრეთ ევროპული"
#: gfls/gfls-encoding-manager-iconv.c:49 gfls/gfls-encoding-manager-iconv.c:56
#: gfls/gfls-encoding-manager-iconv.c:114
msgid "Baltic"
msgstr "ბალტიური"
#: gfls/gfls-encoding-manager-iconv.c:50 gfls/gfls-encoding-manager-iconv.c:88
#: gfls/gfls-encoding-manager-iconv.c:95 gfls/gfls-encoding-manager-iconv.c:97
#: gfls/gfls-encoding-manager-iconv.c:98 gfls/gfls-encoding-manager-iconv.c:108
msgid "Cyrillic"
msgstr "კირილიცა"
#: gfls/gfls-encoding-manager-iconv.c:51 gfls/gfls-encoding-manager-iconv.c:91
#: gfls/gfls-encoding-manager-iconv.c:113
msgid "Arabic"
msgstr "არაბული"
#: gfls/gfls-encoding-manager-iconv.c:52 gfls/gfls-encoding-manager-iconv.c:110
msgid "Greek"
msgstr "ბერძნული"
#: gfls/gfls-encoding-manager-iconv.c:53
msgid "Hebrew Visual"
msgstr "ივრითი ვიზუალი"
#: gfls/gfls-encoding-manager-iconv.c:54 gfls/gfls-encoding-manager-iconv.c:89
#: gfls/gfls-encoding-manager-iconv.c:111
msgid "Turkish"
msgstr "თურქული"
#: gfls/gfls-encoding-manager-iconv.c:55
msgid "Nordic"
msgstr "სკანდინავიური"
#: gfls/gfls-encoding-manager-iconv.c:57
msgid "Celtic"
msgstr "კელტური"
#: gfls/gfls-encoding-manager-iconv.c:59
msgid "Romanian"
msgstr "რუმინული"
#: gfls/gfls-encoding-manager-iconv.c:69
msgid "Armenian"
msgstr "სომხური"
#: gfls/gfls-encoding-manager-iconv.c:70 gfls/gfls-encoding-manager-iconv.c:71
#: gfls/gfls-encoding-manager-iconv.c:79
msgid "Chinese Traditional"
msgstr "ჩინური ტრადიციული"
#: gfls/gfls-encoding-manager-iconv.c:72
msgid "Cyrillic/Russian"
msgstr "კირილიცა/რუსული"
#: gfls/gfls-encoding-manager-iconv.c:74 gfls/gfls-encoding-manager-iconv.c:75
#: gfls/gfls-encoding-manager-iconv.c:76 gfls/gfls-encoding-manager-iconv.c:93
#: gfls/gfls-encoding-manager-iconv.c:101
msgid "Japanese"
msgstr "იაპონური"
#: gfls/gfls-encoding-manager-iconv.c:78 gfls/gfls-encoding-manager-iconv.c:94
#: gfls/gfls-encoding-manager-iconv.c:96 gfls/gfls-encoding-manager-iconv.c:104
msgid "Korean"
msgstr "კორეული"
#: gfls/gfls-encoding-manager-iconv.c:81 gfls/gfls-encoding-manager-iconv.c:82
#: gfls/gfls-encoding-manager-iconv.c:83
msgid "Chinese Simplified"
msgstr "ჩინური გამარტივებული"
#: gfls/gfls-encoding-manager-iconv.c:84
msgid "Georgian"
msgstr "ქართული"
#: gfls/gfls-encoding-manager-iconv.c:90 gfls/gfls-encoding-manager-iconv.c:112
msgid "Hebrew"
msgstr "ივრითი"
#: gfls/gfls-encoding-manager-iconv.c:99
msgid "Cyrillic/Ukrainian"
msgstr "კირილიცა/უკრაინული"
#: gfls/gfls-encoding-manager-iconv.c:102
#: gfls/gfls-encoding-manager-iconv.c:105
#: gfls/gfls-encoding-manager-iconv.c:115
msgid "Vietnamese"
msgstr "ვიეტნამური"
#: gfls/gfls-encoding-manager-iconv.c:103
msgid "Thai"
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-unsaved-document-titles.c:61
#, c-format
msgid "Unsaved Document %d"
msgstr "შეუნახავი დოკუმენტი %d"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/kk.po 0000664 0000000 0000000 00000005237 15166134262 0024014 0 ustar 00root root 0000000 0000000 # 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-03-26 11:38+0000\n"
"PO-Revision-Date: 2026-03-26 22:25+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"
#: 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"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/kw.po 0000664 0000000 0000000 00000002776 15166134262 0024035 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/lt.po 0000664 0000000 0000000 00000002621 15166134262 0024020 0 ustar 00root root 0000000 0000000 # 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: 2025-12-10 20:34+0000\n"
"PO-Revision-Date: 2026-01-10 18:03+0200\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.8\n"
#: 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-unsaved-document-titles.c:61
#, c-format
msgid "Unsaved Document %d"
msgstr "Neįrašytas dokumentas %d"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/meson.build 0000664 0000000 0000000 00000000071 15166134262 0025200 0 ustar 00root root 0000000 0000000 I18N.gettext(
GETTEXT_PACKAGE_NAME,
preset: 'glib'
)
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/pl.po 0000664 0000000 0000000 00000002633 15166134262 0024017 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/pt_BR.po 0000664 0000000 0000000 00000012051 15166134262 0024405 0 ustar 00root root 0000000 0000000 # 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.
#
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-01-13 02:09+0000\n"
"PO-Revision-Date: 2025-01-15 00:23-0300\n"
"Last-Translator: Rafael Fontenelle \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 47.1\n"
#. Translators: the first %s is a category, the second %s is the
#. * name.
#.
#: gfls/gfls-encoding.c:203
#, c-format
msgid "%s (%s)"
msgstr "%s (%s)"
#. UTF-8 first, so that it's the first encoding returned by
#. * tepl_encoding_iconv_get_all().
#.
#: gfls/gfls-encoding-manager-iconv.c:44 gfls/gfls-encoding-manager-iconv.c:61
#: gfls/gfls-encoding-manager-iconv.c:62 gfls/gfls-encoding-manager-iconv.c:63
#: gfls/gfls-encoding-manager-iconv.c:64 gfls/gfls-encoding-manager-iconv.c:65
#: gfls/gfls-encoding-manager-iconv.c:66 gfls/gfls-encoding-manager-iconv.c:67
msgid "Unicode"
msgstr "Unicode"
#. FIXME GEOSTD8 ?
#: gfls/gfls-encoding-manager-iconv.c:46 gfls/gfls-encoding-manager-iconv.c:58
#: gfls/gfls-encoding-manager-iconv.c:86 gfls/gfls-encoding-manager-iconv.c:109
msgid "Western"
msgstr "Ocidental"
#: gfls/gfls-encoding-manager-iconv.c:47 gfls/gfls-encoding-manager-iconv.c:87
#: gfls/gfls-encoding-manager-iconv.c:107
msgid "Central European"
msgstr "Centro europeu"
#: gfls/gfls-encoding-manager-iconv.c:48
msgid "South European"
msgstr "Europa sulista"
#: gfls/gfls-encoding-manager-iconv.c:49 gfls/gfls-encoding-manager-iconv.c:56
#: gfls/gfls-encoding-manager-iconv.c:114
msgid "Baltic"
msgstr "Báltico"
#: gfls/gfls-encoding-manager-iconv.c:50 gfls/gfls-encoding-manager-iconv.c:88
#: gfls/gfls-encoding-manager-iconv.c:95 gfls/gfls-encoding-manager-iconv.c:97
#: gfls/gfls-encoding-manager-iconv.c:98 gfls/gfls-encoding-manager-iconv.c:108
msgid "Cyrillic"
msgstr "Cirílico"
#: gfls/gfls-encoding-manager-iconv.c:51 gfls/gfls-encoding-manager-iconv.c:91
#: gfls/gfls-encoding-manager-iconv.c:113
msgid "Arabic"
msgstr "Árabe"
#: gfls/gfls-encoding-manager-iconv.c:52 gfls/gfls-encoding-manager-iconv.c:110
msgid "Greek"
msgstr "Grego"
#: gfls/gfls-encoding-manager-iconv.c:53
msgid "Hebrew Visual"
msgstr "Hebraico visual"
#: gfls/gfls-encoding-manager-iconv.c:54 gfls/gfls-encoding-manager-iconv.c:89
#: gfls/gfls-encoding-manager-iconv.c:111
msgid "Turkish"
msgstr "Turco"
#: gfls/gfls-encoding-manager-iconv.c:55
msgid "Nordic"
msgstr "Nórdico"
#: gfls/gfls-encoding-manager-iconv.c:57
msgid "Celtic"
msgstr "Céltico"
#: gfls/gfls-encoding-manager-iconv.c:59
msgid "Romanian"
msgstr "Romeno"
#: gfls/gfls-encoding-manager-iconv.c:69
msgid "Armenian"
msgstr "Armênio"
#: gfls/gfls-encoding-manager-iconv.c:70 gfls/gfls-encoding-manager-iconv.c:71
#: gfls/gfls-encoding-manager-iconv.c:79
msgid "Chinese Traditional"
msgstr "Chinês tradicional"
#: gfls/gfls-encoding-manager-iconv.c:72
msgid "Cyrillic/Russian"
msgstr "Cirílico/Russo"
#: gfls/gfls-encoding-manager-iconv.c:74 gfls/gfls-encoding-manager-iconv.c:75
#: gfls/gfls-encoding-manager-iconv.c:76 gfls/gfls-encoding-manager-iconv.c:93
#: gfls/gfls-encoding-manager-iconv.c:101
msgid "Japanese"
msgstr "Japonês"
#: gfls/gfls-encoding-manager-iconv.c:78 gfls/gfls-encoding-manager-iconv.c:94
#: gfls/gfls-encoding-manager-iconv.c:96 gfls/gfls-encoding-manager-iconv.c:104
msgid "Korean"
msgstr "Coreano"
#: gfls/gfls-encoding-manager-iconv.c:81 gfls/gfls-encoding-manager-iconv.c:82
#: gfls/gfls-encoding-manager-iconv.c:83
msgid "Chinese Simplified"
msgstr "Chinês simplificado"
#: gfls/gfls-encoding-manager-iconv.c:84
msgid "Georgian"
msgstr "Georgiano"
#: gfls/gfls-encoding-manager-iconv.c:90 gfls/gfls-encoding-manager-iconv.c:112
msgid "Hebrew"
msgstr "Hebraico"
#: gfls/gfls-encoding-manager-iconv.c:99
msgid "Cyrillic/Ukrainian"
msgstr "Cirílico/Ucraniano"
#: gfls/gfls-encoding-manager-iconv.c:102
#: gfls/gfls-encoding-manager-iconv.c:105
#: gfls/gfls-encoding-manager-iconv.c:115
msgid "Vietnamese"
msgstr "Vietinamita"
#: gfls/gfls-encoding-manager-iconv.c:103
msgid "Thai"
msgstr "Tailandês"
#: 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-unsaved-document-titles.c:61
#, c-format
msgid "Unsaved Document %d"
msgstr "Documento não salvo %d"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/ru.po 0000664 0000000 0000000 00000010337 15166134262 0024032 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/sl.po 0000664 0000000 0000000 00000004472 15166134262 0024025 0 ustar 00root root 0000000 0000000 # 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.
#
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-03-26 18:15+0100\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"
#: gfls/gfls-encoding-convert.c:344
#, c-format
msgid "A number of nonreversible conversions have been performed."
msgstr "Opravljenih je bilo več nepovratnih pretvorb."
#: gfls/gfls-encoding-convert.c:358
#, c-format
msgid "An invalid character has been encountered."
msgstr "Zaznan je bil neveljaven znak."
#: 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:138
#, 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:147
#, 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:217
#, c-format
msgid "Error during character set conversion: %s"
msgstr "Napaka med pretvorbo nabora znakov: %s"
#: gfls/gfls-iconv.c:309
#, 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/sr.po 0000664 0000000 0000000 00000007731 15166134262 0024034 0 ustar 00root root 0000000 0000000 # 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/sv.po 0000664 0000000 0000000 00000007042 15166134262 0024033 0 ustar 00root root 0000000 0000000 # 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-03-26 11:38+0000\n"
"PO-Revision-Date: 2026-03-22 16:59+0100\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.8\n"
#: gfls/gfls-encoding-convert.c:344
#, c-format
msgid "A number of nonreversible conversions have been performed."
msgstr "Ett antal irreversibla konverteringar har utförts."
#: gfls/gfls-encoding-convert.c:358
#, c-format
msgid "An invalid character has been encountered."
msgstr "Ett ogiltigt tecken har påträffats."
#: 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:138
#, 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:147
#, 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:217
#, c-format
msgid "Error during character set conversion: %s"
msgstr "Fel under konvertering av teckenuppsättning: %s"
#: gfls/gfls-iconv.c:309
#, 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 "%s (%s)"
#~ msgstr "%s (%s)"
#~ msgid "Unicode"
#~ msgstr "Unicode"
#~ msgid "Western"
#~ msgstr "Västerländsk"
#~ msgid "Central European"
#~ msgstr "Centraleuropeisk"
#~ msgid "South European"
#~ msgstr "Sydeuropeisk"
#~ msgid "Baltic"
#~ msgstr "Baltisk"
#~ msgid "Cyrillic"
#~ msgstr "Kyrillisk"
#~ msgid "Arabic"
#~ msgstr "Arabisk"
#~ msgid "Greek"
#~ msgstr "Grekisk"
#~ msgid "Hebrew Visual"
#~ msgstr "Hebreisk visuell"
#~ msgid "Turkish"
#~ msgstr "Turkisk"
#~ msgid "Nordic"
#~ msgstr "Nordisk"
#~ msgid "Celtic"
#~ msgstr "Keltisk"
#~ msgid "Romanian"
#~ msgstr "Rumänsk"
#~ msgid "Armenian"
#~ msgstr "Armenisk"
#~ msgid "Chinese Traditional"
#~ msgstr "Traditionell kinesisk"
#~ msgid "Cyrillic/Russian"
#~ msgstr "Kyrillisk/rysk"
#~ msgid "Japanese"
#~ msgstr "Japansk"
#~ msgid "Korean"
#~ msgstr "Koreansk"
#~ msgid "Chinese Simplified"
#~ msgstr "Förenklad kinesisk"
#~ msgid "Georgian"
#~ msgstr "Georgisk"
#~ msgid "Hebrew"
#~ msgstr "Hebreisk"
#~ msgid "Cyrillic/Ukrainian"
#~ msgstr "Kyrillisk/ukrainsk"
#~ msgid "Vietnamese"
#~ msgstr "Vietnamesisk"
#~ msgid "Thai"
#~ msgstr "Thailändsk"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/tr.po 0000664 0000000 0000000 00000002504 15166134262 0024026 0 ustar 00root root 0000000 0000000 # 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.
#
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-03 19:24+0300\n"
"Last-Translator: Sabri Ünal \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.5\n"
#: 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-unsaved-document-titles.c:61
#, c-format
msgid "Unsaved Document %d"
msgstr "Kaydedilmemiş Belge %d"
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/uk.po 0000664 0000000 0000000 00000010452 15166134262 0024021 0 ustar 00root root 0000000 0000000 # 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.
#
# Yuri Chornoivan , 2024, 2025, 2026.
msgid ""
msgstr ""
"Project-Id-Version: libgedit-gfls main\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/gedit/libgedit-gfls/-/is"
"sues\n"
"POT-Creation-Date: 2026-03-26 11:38+0000\n"
"PO-Revision-Date: 2026-03-26 21:37+0200\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 23.04.3\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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/po/zh_CN.po 0000664 0000000 0000000 00000006575 15166134262 0024416 0 ustar 00root root 0000000 0000000 # 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-03-26 11:38+0000\n"
"PO-Revision-Date: 2026-04-03 09:28+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 50.0\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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/ 0000775 0000000 0000000 00000000000 15166134262 0023564 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/interactive-tests/ 0000775 0000000 0000000 00000000000 15166134262 0027241 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/interactive-tests/gfls-gui.c 0000664 0000000 0000000 00000014164 15166134262 0031130 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/interactive-tests/gfls-program.c 0000664 0000000 0000000 00000006240 15166134262 0032007 0 ustar 00root root 0000000 0000000 /* 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.c 0000664 0000000 0000000 00000012733 15166134262 0034535 0 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/interactive-tests/meson.build 0000664 0000000 0000000 00000000470 15166134262 0031404 0 ustar 00root root 0000000 0000000 executable(
'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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/meson.build 0000664 0000000 0000000 00000000061 15166134262 0025723 0 ustar 00root root 0000000 0000000 subdir('interactive-tests')
subdir('unit-tests')
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests/ 0000775 0000000 0000000 00000000000 15166134262 0025703 5 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests/meson.build 0000664 0000000 0000000 00000000572 15166134262 0030051 0 ustar 00root root 0000000 0000000 unit_tests = [
'test-attribute-keys',
'test-bytes-region',
'test-encoding-conversion',
'test-encoding-convert',
'test-iconv',
'test-input-stream',
'test-unsaved-document-titles',
'test-utf8',
]
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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests/test-attribute-keys.c 0000664 0000000 0000000 00000001655 15166134262 0032007 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests/test-bytes-region.c 0000664 0000000 0000000 00000007373 15166134262 0031445 0 ustar 00root root 0000000 0000000 /* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include
static void
test_empty (void)
{
GflsBytesRegionBuilder *builder;
GflsBytesRegion *region;
gsize total_size;
gchar *str;
builder = gfls_bytes_region_builder_new ();
total_size = gfls_bytes_region_builder_get_current_size (builder);
g_assert_cmpuint (total_size, ==, 0);
region = gfls_bytes_region_builder_free (builder, FALSE);
builder = NULL;
str = gfls_bytes_region_to_string (region);
g_assert_nonnull (str);
g_assert_cmpstr (str, ==, "");
g_free (str);
gfls_bytes_region_free (region);
}
static void
test_single_sub_region_part_of_region (void)
{
GflsBytesRegionBuilder *builder;
GflsBytesRegion *region;
gsize total_size;
gchar *str;
builder = gfls_bytes_region_builder_new ();
gfls_bytes_region_builder_append (builder, 3, TRUE);
total_size = gfls_bytes_region_builder_get_current_size (builder);
g_assert_cmpuint (total_size, ==, 3);
region = gfls_bytes_region_builder_free (builder, FALSE);
builder = NULL;
str = gfls_bytes_region_to_string (region);
g_assert_nonnull (str);
g_assert_cmpstr (str, ==, "[0, 3, 1]\n");
g_free (str);
gfls_bytes_region_free (region);
}
static void
test_single_sub_region_not_part_of_region (void)
{
GflsBytesRegionBuilder *builder;
GflsBytesRegion *region;
gsize total_size;
gchar *str;
builder = gfls_bytes_region_builder_new ();
gfls_bytes_region_builder_append (builder, 4, FALSE);
total_size = gfls_bytes_region_builder_get_current_size (builder);
g_assert_cmpuint (total_size, ==, 4);
region = gfls_bytes_region_builder_free (builder, FALSE);
builder = NULL;
str = gfls_bytes_region_to_string (region);
g_assert_nonnull (str);
g_assert_cmpstr (str, ==, "[0, 4, 0]\n");
g_free (str);
gfls_bytes_region_free (region);
}
static void
test_merge (void)
{
GflsBytesRegionBuilder *builder;
GflsBytesRegion *region;
gsize total_size;
gchar *str;
builder = gfls_bytes_region_builder_new ();
gfls_bytes_region_builder_append (builder, 5, TRUE);
gfls_bytes_region_builder_append (builder, 5, TRUE);
gfls_bytes_region_builder_append (builder, 2, FALSE);
gfls_bytes_region_builder_append (builder, 2, FALSE);
total_size = gfls_bytes_region_builder_get_current_size (builder);
g_assert_cmpuint (total_size, ==, 14);
region = gfls_bytes_region_builder_free (builder, FALSE);
builder = NULL;
str = gfls_bytes_region_to_string (region);
g_assert_nonnull (str);
g_assert_cmpstr (str, ==,
"[0, 10, 1]\n"
"[10, 4, 0]\n");
g_free (str);
gfls_bytes_region_free (region);
}
static void
test_match_bytes (void)
{
GflsBytesRegionBuilder *builder;
GflsBytesRegion *region;
GBytes *bytes;
builder = gfls_bytes_region_builder_new ();
gfls_bytes_region_builder_append (builder, 2, TRUE);
gfls_bytes_region_builder_append (builder, 1, FALSE);
region = gfls_bytes_region_builder_free (builder, FALSE);
builder = NULL;
bytes = g_bytes_new_static ("abc", 3);
g_assert_true (gfls_bytes_region_match_bytes (region, bytes));
g_bytes_unref (bytes);
bytes = g_bytes_new_static ("a", 1);
g_assert_false (gfls_bytes_region_match_bytes (region, bytes));
g_bytes_unref (bytes);
gfls_bytes_region_free (region);
}
int
main (int argc,
char **argv)
{
int exit_status;
gfls_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/BytesRegion/empty", test_empty);
g_test_add_func ("/BytesRegion/single_sub_region_part_of_region", test_single_sub_region_part_of_region);
g_test_add_func ("/BytesRegion/single_sub_region_not_part_of_region", test_single_sub_region_not_part_of_region);
g_test_add_func ("/BytesRegion/merge", test_merge);
g_test_add_func ("/BytesRegion/match_bytes", test_match_bytes);
exit_status = g_test_run ();
gfls_finalize ();
return exit_status;
}
test-encoding-conversion.c 0000664 0000000 0000000 00000002305 15166134262 0032716 0 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/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-convert.c 0000664 0000000 0000000 00000013716 15166134262 0032221 0 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests /* SPDX-FileCopyrightText: 2026 - Sébastien Wilmet
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include
static void
test_iconv_open_failure (void)
{
GBytes *input_bytes;
GBytes *output_bytes = NULL;
GflsBytesRegion *output_bytes_valid_region = NULL;
gboolean success;
GError *error = NULL;
input_bytes = g_bytes_new_static ("a", 1);
success = gfls_encoding_convert (input_bytes,
"UTF-8",
"CANNOT_POSSIBLY_WORK",
TRUE,
&output_bytes,
&output_bytes_valid_region,
&error);
g_assert_false (success);
g_assert_nonnull (error);
g_bytes_unref (input_bytes);
g_bytes_unref (output_bytes);
gfls_bytes_region_free (output_bytes_valid_region);
g_clear_error (&error);
}
static void
test_basic (void)
{
GBytes *input_bytes;
GBytes *output_bytes = NULL;
GflsBytesRegion *output_bytes_valid_region = NULL;
gboolean success;
gchar *region_str;
GError *error = NULL;
input_bytes = g_bytes_new_static ("oh", 2);
success = gfls_encoding_convert (input_bytes,
"UTF-8",
"ISO-8859-15",
TRUE,
&output_bytes,
&output_bytes_valid_region,
&error);
g_assert_true (success);
g_assert_no_error (error);
g_assert_true (g_bytes_equal (input_bytes, output_bytes));
region_str = gfls_bytes_region_to_string (output_bytes_valid_region);
g_assert_cmpstr ("[0, 2, 1]\n", ==, region_str);
g_bytes_unref (input_bytes);
g_bytes_unref (output_bytes);
gfls_bytes_region_free (output_bytes_valid_region);
g_free (region_str);
}
static void
test_illegal_sequence (void)
{
guint8 input_buffer[1] = { 255 }; // See also test-iconv.c
GBytes *input_bytes;
GBytes *output_bytes = NULL;
GflsBytesRegion *output_bytes_valid_region = NULL;
gboolean success;
gchar *region_str;
GError *error = NULL;
input_bytes = g_bytes_new_static (input_buffer, 1);
success = gfls_encoding_convert (input_bytes,
"UTF-8",
"UTF-8",
TRUE,
&output_bytes,
&output_bytes_valid_region,
&error);
g_assert_true (success);
g_assert_no_error (error);
g_assert_true (g_bytes_equal (input_bytes, output_bytes));
region_str = gfls_bytes_region_to_string (output_bytes_valid_region);
g_assert_cmpstr ("[0, 1, 0]\n", ==, region_str);
g_bytes_unref (input_bytes);
g_bytes_unref (output_bytes);
gfls_bytes_region_free (output_bytes_valid_region);
g_free (region_str);
}
static void
test_incomplete_input (void)
{
guint8 input_buffer[1] = { 195 }; // See also test-iconv.c
GBytes *input_bytes;
GBytes *output_bytes = NULL;
GflsBytesRegion *output_bytes_valid_region = NULL;
gboolean success;
gchar *region_str;
GError *error = NULL;
input_bytes = g_bytes_new_static (input_buffer, 1);
success = gfls_encoding_convert (input_bytes,
"UTF-8",
"UTF-8",
TRUE,
&output_bytes,
&output_bytes_valid_region,
&error);
g_assert_true (success);
g_assert_no_error (error);
g_assert_true (g_bytes_equal (input_bytes, output_bytes));
region_str = gfls_bytes_region_to_string (output_bytes_valid_region);
g_assert_cmpstr ("[0, 1, 0]\n", ==, region_str);
g_bytes_unref (input_bytes);
g_bytes_unref (output_bytes);
gfls_bytes_region_free (output_bytes_valid_region);
g_free (region_str);
}
static void
test_buffer_full (void)
{
gsize input_size = 32 * 1024;
gchar *input_str;
GBytes *input_bytes;
GBytes *output_bytes = NULL;
GflsBytesRegion *output_bytes_valid_region = NULL;
gboolean success;
gchar *region_str;
GError *error = NULL;
input_str = g_strnfill (input_size, 'a');
input_bytes = g_bytes_new_take (input_str, input_size);
input_str = NULL;
success = gfls_encoding_convert (input_bytes,
"UTF-16LE",
"UTF-8",
TRUE,
&output_bytes,
&output_bytes_valid_region,
&error);
g_assert_true (success);
g_assert_no_error (error);
{
const guint8 *output_data;
gsize output_size = 0;
output_data = g_bytes_get_data (output_bytes, &output_size);
g_assert_cmpuint (output_size, ==, input_size * 2);
g_assert_cmpuint (output_data[0], ==, 97);
g_assert_cmpuint (output_data[1], ==, 0);
g_assert_cmpuint (output_data[2], ==, 97);
g_assert_cmpuint (output_data[3], ==, 0);
g_assert_cmpuint (output_data[4], ==, 97);
g_assert_cmpuint (output_data[5], ==, 0);
// Etc.
}
region_str = gfls_bytes_region_to_string (output_bytes_valid_region);
g_assert_cmpstr ("[0, 65536, 1]\n", ==, region_str);
g_bytes_unref (input_bytes);
g_bytes_unref (output_bytes);
gfls_bytes_region_free (output_bytes_valid_region);
g_free (region_str);
}
static void
test_lossy_conversion (void)
{
// See also test-iconv.c.
// "é": Latin Small Letter E With Acute (U+00E9)
guint8 input_buffer[2] = { 195, 169 };
GBytes *input_bytes;
GBytes *output_bytes = NULL;
GflsBytesRegion *output_bytes_valid_region = NULL;
gboolean success;
GError *error = NULL;
input_bytes = g_bytes_new_static (input_buffer, 2);
success = gfls_encoding_convert (input_bytes,
"ASCII//TRANSLIT",
"UTF-8",
TRUE,
&output_bytes,
&output_bytes_valid_region,
&error);
g_assert_false (success);
g_assert_null (output_bytes);
g_assert_null (output_bytes_valid_region);
g_assert_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED);
g_bytes_unref (input_bytes);
g_clear_error (&error);
// For better code coverage (output_bytes_valid_region is NULL).
gfls_bytes_region_free (output_bytes_valid_region);
}
int
main (int argc,
char **argv)
{
int exit_status;
gfls_init ();
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/EncodingConvert/iconv_open_failure", test_iconv_open_failure);
g_test_add_func ("/EncodingConvert/basic", test_basic);
g_test_add_func ("/EncodingConvert/illegal_sequence", test_illegal_sequence);
g_test_add_func ("/EncodingConvert/incomplete_input", test_incomplete_input);
g_test_add_func ("/EncodingConvert/buffer_full", test_buffer_full);
g_test_add_func ("/EncodingConvert/lossy_conversion", test_lossy_conversion);
exit_status = g_test_run ();
gfls_finalize ();
return exit_status;
}
libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests/test-iconv.c 0000664 0000000 0000000 00000024453 15166134262 0030152 0 ustar 00root root 0000000 0000000 /* 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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests/test-input-stream.c 0000664 0000000 0000000 00000005011 15166134262 0031451 0 ustar 00root root 0000000 0000000 /* 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.c 0000664 0000000 0000000 00000003505 15166134262 0033533 0 ustar 00root root 0000000 0000000 libgedit-gfls-0.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/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.4.1-ce4b836dfda4ea3f594b9ded7b60c5cb51ccbc87/tests/unit-tests/test-utf8.c 0000664 0000000 0000000 00000004074 15166134262 0027717 0 ustar 00root root 0000000 0000000 /* 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);
}
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);
exit_status = g_test_run ();
gfls_finalize ();
return exit_status;
}