mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 07:26:15 +01:00
Merge branch 'migrate-to-gi-docgen2' into 'main'
Switch to using gi-docgen for docs (batch 2) See merge request GNOME/glib!3634
This commit is contained in:
commit
20b0d292ca
@ -61,7 +61,7 @@ variables:
|
|||||||
extends: .only-default
|
extends: .only-default
|
||||||
before_script:
|
before_script:
|
||||||
- rm -rf subprojects/gvdb
|
- rm -rf subprojects/gvdb
|
||||||
- git config --global --add safe.directory $(pwd)
|
- git config --global --add safe.directory "${PWD}"
|
||||||
- git submodule update --init --depth 1
|
- git submodule update --init --depth 1
|
||||||
variables:
|
variables:
|
||||||
GIT_SUBMODULE_STRATEGY: "none"
|
GIT_SUBMODULE_STRATEGY: "none"
|
||||||
@ -82,6 +82,7 @@ sh-and-py-check:
|
|||||||
stage: style-check
|
stage: style-check
|
||||||
allow_failure: false
|
allow_failure: false
|
||||||
script:
|
script:
|
||||||
|
- git config --global --add safe.directory "${PWD}"
|
||||||
- .gitlab-ci/run-shellcheck.sh
|
- .gitlab-ci/run-shellcheck.sh
|
||||||
- .gitlab-ci/run-black.sh
|
- .gitlab-ci/run-black.sh
|
||||||
- .gitlab-ci/run-flake8.sh
|
- .gitlab-ci/run-flake8.sh
|
||||||
|
@ -18,6 +18,7 @@ RUN dnf -y update \
|
|||||||
gi-docgen \
|
gi-docgen \
|
||||||
git \
|
git \
|
||||||
glibc-devel \
|
glibc-devel \
|
||||||
|
glibc-gconv-extra \
|
||||||
glibc-headers \
|
glibc-headers \
|
||||||
glibc-langpack-de \
|
glibc-langpack-de \
|
||||||
glibc-langpack-el \
|
glibc-langpack-el \
|
||||||
|
517
docs/reference/glib/data-structures.md
Normal file
517
docs/reference/glib/data-structures.md
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
Title: Data Structures
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
SPDX-FileCopyrightText: 2010 Allison Lortie
|
||||||
|
SPDX-FileCopyrightText: 2011 Collabora, Ltd.
|
||||||
|
SPDX-FileCopyrightText: 2012 Olivier Sessink
|
||||||
|
SPDX-FileCopyrightText: 2010, 2011, 2014 Matthias Clasen
|
||||||
|
SPDX-FileCopyrightText: 2018 Sébastien Wilmet
|
||||||
|
SPDX-FileCopyrightText: 2018 Emmanuele Bassi
|
||||||
|
SPDX-FileCopyrightText: 2019 Emmanuel Fleury
|
||||||
|
SPDX-FileCopyrightText: 2017, 2018, 2019 Endless Mobile, Inc.
|
||||||
|
SPDX-FileCopyrightText: 2020 Endless OS Foundation, LLC
|
||||||
|
|
||||||
|
# Data Structures
|
||||||
|
|
||||||
|
GLib includes a number of basic data sructures, such as arrays, linked lists, hash tables,
|
||||||
|
queues, trees, etc.
|
||||||
|
|
||||||
|
## Arrays
|
||||||
|
|
||||||
|
GLib arrays ([struct@GLib.Array]) are similar to standard C arrays, except that they grow
|
||||||
|
automatically as elements are added.
|
||||||
|
|
||||||
|
Array elements can be of any size (though all elements of one array are the same size),
|
||||||
|
and the array can be automatically cleared to '0's and zero-terminated.
|
||||||
|
|
||||||
|
To create a new array use [func@GLib.Array.new].
|
||||||
|
|
||||||
|
To add elements to an array with a cost of O(n) at worst, use
|
||||||
|
[func@GLib.array_append_val],
|
||||||
|
[func@GLib.Array.append_vals],
|
||||||
|
[func@GLib.array_prepend_val],
|
||||||
|
[func@GLib.Array.prepend_vals],
|
||||||
|
[func@GLib.array_insert_val] and
|
||||||
|
[func@GLib.Array.insert_vals].
|
||||||
|
|
||||||
|
To access an element of an array in O(1) (to read it or to write it),
|
||||||
|
use [func@GLib.array_index].
|
||||||
|
|
||||||
|
To set the size of an array, use [func@GLib.Array.set_size].
|
||||||
|
|
||||||
|
To free an array, use [func@GLib.Array.unref] or [func@GLib.Array.free].
|
||||||
|
|
||||||
|
All the sort functions are internally calling a quick-sort (or similar)
|
||||||
|
function with an average cost of O(n log(n)) and a worst case cost of O(n^2).
|
||||||
|
|
||||||
|
Here is an example that stores integers in a [struct@GLib.Array]:
|
||||||
|
|
||||||
|
```c
|
||||||
|
GArray *array;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// We create a new array to store int values.
|
||||||
|
// We don't want it zero-terminated or cleared to 0's.
|
||||||
|
array = g_array_new (FALSE, FALSE, sizeof (int));
|
||||||
|
|
||||||
|
for (i = 0; i < 10000; i++)
|
||||||
|
{
|
||||||
|
g_array_append_val (array, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10000; i++)
|
||||||
|
{
|
||||||
|
if (g_array_index (array, int, i) != i)
|
||||||
|
g_print ("ERROR: got %d instead of %d\n",
|
||||||
|
g_array_index (array, int, i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free (array, TRUE);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pointer Arrays
|
||||||
|
|
||||||
|
Pointer Arrays ([struct@GLib.PtrArray]) are similar to Arrays but are used
|
||||||
|
only for storing pointers.
|
||||||
|
|
||||||
|
If you remove elements from the array, elements at the end of the
|
||||||
|
array are moved into the space previously occupied by the removed
|
||||||
|
element. This means that you should not rely on the index of particular
|
||||||
|
elements remaining the same. You should also be careful when deleting
|
||||||
|
elements while iterating over the array.
|
||||||
|
|
||||||
|
To create a pointer array, use [func@GLib.PtrArray.new].
|
||||||
|
|
||||||
|
To add elements to a pointer array, use [func@GLib.PtrArray.add].
|
||||||
|
|
||||||
|
To remove elements from a pointer array, use
|
||||||
|
[func@GLib.PtrArray.remove],
|
||||||
|
[func@GLib.PtrArray.remove_index] or
|
||||||
|
[func@GLib.PtrArray.remove_index_fast].
|
||||||
|
|
||||||
|
To access an element of a pointer array, use [func@GLib.ptr_array_index].
|
||||||
|
|
||||||
|
To set the size of a pointer array, use [func@GLib.PtrArray.set_size].
|
||||||
|
|
||||||
|
To free a pointer array, use [func@GLib.PtrArray.unref] or [func@GLib.PtrArray.free].
|
||||||
|
|
||||||
|
An example using a [struct@GLib.PtrArray]:
|
||||||
|
|
||||||
|
```c
|
||||||
|
GPtrArray *array;
|
||||||
|
char *string1 = "one";
|
||||||
|
char *string2 = "two";
|
||||||
|
char *string3 = "three";
|
||||||
|
|
||||||
|
array = g_ptr_array_new ();
|
||||||
|
g_ptr_array_add (array, (gpointer) string1);
|
||||||
|
g_ptr_array_add (array, (gpointer) string2);
|
||||||
|
g_ptr_array_add (array, (gpointer) string3);
|
||||||
|
|
||||||
|
if (g_ptr_array_index (array, 0) != (gpointer) string1)
|
||||||
|
g_print ("ERROR: got %p instead of %p\n",
|
||||||
|
g_ptr_array_index (array, 0), string1);
|
||||||
|
|
||||||
|
g_ptr_array_free (array, TRUE);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Byte Arrays
|
||||||
|
|
||||||
|
[struct@GLib.ByteArray] is a mutable array of bytes based on [struct@GLib.Array],
|
||||||
|
to provide arrays of bytes which grow automatically as elements are added.
|
||||||
|
|
||||||
|
To create a new `GByteArray` use [func@GLib.ByteArray.new].
|
||||||
|
|
||||||
|
To add elements to a `GByteArray`, use
|
||||||
|
[func@GLib.ByteArray.append] and [func@GLib.ByteArray.prepend].
|
||||||
|
|
||||||
|
To set the size of a `GByteArray`, use [func@GLib.ByteArray.set_size].
|
||||||
|
|
||||||
|
To free a `GByteArray`, use [func@GLib.ByteArray.unref] or [func@GLib.ByteArray.free].
|
||||||
|
|
||||||
|
An example for using a `GByteArray`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
GByteArray *array;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
array = g_byte_array_new ();
|
||||||
|
for (i = 0; i < 10000; i++)
|
||||||
|
{
|
||||||
|
g_byte_array_append (array, (guint8*) "abcd", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10000; i++)
|
||||||
|
{
|
||||||
|
g_assert (array->data[4*i] == 'a');
|
||||||
|
g_assert (array->data[4*i+1] == 'b');
|
||||||
|
g_assert (array->data[4*i+2] == 'c');
|
||||||
|
g_assert (array->data[4*i+3] == 'd');
|
||||||
|
}
|
||||||
|
|
||||||
|
g_byte_array_free (array, TRUE);
|
||||||
|
```
|
||||||
|
|
||||||
|
See [struct@GLib.Bytes] if you are interested in an immutable object representing a
|
||||||
|
sequence of bytes.
|
||||||
|
|
||||||
|
## Singly-linked Lists
|
||||||
|
|
||||||
|
The [struct@GLib.SList] structure and its associated functions provide a standard
|
||||||
|
singly-linked list data structure. The benefit of this data structure is to provide
|
||||||
|
insertion/deletion operations in O(1) complexity where access/search operations are
|
||||||
|
in O(n). The benefit of `GSList` over [struct@GLib.List] (doubly-linked list) is that
|
||||||
|
they are lighter in space as they only need to retain one pointer but it double the
|
||||||
|
cost of the worst case access/search operations.
|
||||||
|
|
||||||
|
Each element in the list contains a piece of data, together with a pointer which links
|
||||||
|
to the next element in the list. Using this pointer it is possible to move through the
|
||||||
|
list in one direction only (unlike the [doubly-linked lists](#doubly-linked-lists),
|
||||||
|
which allow movement in both directions).
|
||||||
|
|
||||||
|
The data contained in each element can be either integer values, by
|
||||||
|
using one of the [Type Conversion Macros](conversion-macros.html),
|
||||||
|
or simply pointers to any type of data.
|
||||||
|
|
||||||
|
Note that most of the #GSList functions expect to be passed a pointer to the first element
|
||||||
|
in the list. The functions which insert elements return the new start of the list, which
|
||||||
|
may have changed.
|
||||||
|
|
||||||
|
There is no function to create a `GSList`. `NULL` is considered to be the empty list so you
|
||||||
|
simply set a `GSList*` to `NULL`.
|
||||||
|
|
||||||
|
To add elements, use [func@GLib.SList.append], [func@GLib.SList.prepend],
|
||||||
|
[func@GLib.SList.insert] and [func@GLib.SList.insert_sorted].
|
||||||
|
|
||||||
|
To remove elements, use [func@GLib.SList.remove].
|
||||||
|
|
||||||
|
To find elements in the list use [func@GLib.SList.last], [func@GLib.slist_next],
|
||||||
|
[func@GLib.SList.nth], [func@GLib.SList.nth_data], [func@GLib.SList.find] and
|
||||||
|
[func@GLib.SList.find_custom].
|
||||||
|
|
||||||
|
To find the index of an element use [func@GLib.SList.position] and [func@GLib.SList.index].
|
||||||
|
|
||||||
|
To call a function for each element in the list use [func@GLib.SList.foreach].
|
||||||
|
|
||||||
|
To free the entire list, use [func@GLib.SList.free].
|
||||||
|
|
||||||
|
## Doubly-linked Lists
|
||||||
|
|
||||||
|
The [struct@GLib.List] structure and its associated functions provide a standard
|
||||||
|
doubly-linked list data structure. The benefit of this data-structure is to provide
|
||||||
|
insertion/deletion operations in O(1) complexity where access/search operations are in O(n).
|
||||||
|
The benefit of `GList` over [struct@GLib.SList] (singly-linked list) is that the worst case
|
||||||
|
on access/search operations is divided by two which comes at a cost in space as we need
|
||||||
|
to retain two pointers in place of one.
|
||||||
|
|
||||||
|
Each element in the list contains a piece of data, together with pointers which link to the
|
||||||
|
previous and next elements in the list. Using these pointers it is possible to move through
|
||||||
|
the list in both directions (unlike the singly-linked [struct@GLib.SList],
|
||||||
|
which only allows movement through the list in the forward direction).
|
||||||
|
|
||||||
|
The doubly-linked list does not keep track of the number of items and does not keep track of
|
||||||
|
both the start and end of the list. If you want fast access to both the start and the end of
|
||||||
|
the list, and/or the number of items in the list, use a [struct@GLib.Queue] instead.
|
||||||
|
|
||||||
|
The data contained in each element can be either integer values, by using one of the
|
||||||
|
[Type Conversion Macros](conversion-macros.html), or simply pointers to any type of data.
|
||||||
|
|
||||||
|
Note that most of the `GList` functions expect to be passed a pointer to the first element in the list.
|
||||||
|
The functions which insert elements return the new start of the list, which may have changed.
|
||||||
|
|
||||||
|
There is no function to create a `GList`. `NULL` is considered to be a valid, empty list so you simply
|
||||||
|
set a `GList*` to `NULL` to initialize it.
|
||||||
|
|
||||||
|
To add elements, use [func@GLib.List.append], [func@GLib.List.prepend],
|
||||||
|
[func@GLib.List.insert] and [func@GLib.List.insert_sorted].
|
||||||
|
|
||||||
|
To visit all elements in the list, use a loop over the list:
|
||||||
|
|
||||||
|
```c
|
||||||
|
GList *l;
|
||||||
|
for (l = list; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
// do something with l->data
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To call a function for each element in the list, use [func@GLib.List.foreach].
|
||||||
|
|
||||||
|
To loop over the list and modify it (e.g. remove a certain element) a while loop is more appropriate,
|
||||||
|
for example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
GList *l = list;
|
||||||
|
while (l != NULL)
|
||||||
|
{
|
||||||
|
GList *next = l->next;
|
||||||
|
if (should_be_removed (l))
|
||||||
|
{
|
||||||
|
// possibly free l->data
|
||||||
|
list = g_list_delete_link (list, l);
|
||||||
|
}
|
||||||
|
l = next;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To remove elements, use [func@GLib.List.remove].
|
||||||
|
|
||||||
|
To navigate in a list, use [func@GLib.List.first], [func@GLib.List.last],
|
||||||
|
[func@GLib.list_next], [func@GLib.list_previous].
|
||||||
|
|
||||||
|
To find elements in the list use [func@GLib.List.nth], [func@GLib.List.nth_data],
|
||||||
|
[func@GLib.List.find] and [func@GLib.List.find_custom].
|
||||||
|
|
||||||
|
To find the index of an element use [func@GLib.List.position] and [func@GLib.List.index].
|
||||||
|
|
||||||
|
To free the entire list, use [func@GLib.List.free] or [func@GLib.List.free_full].
|
||||||
|
|
||||||
|
|
||||||
|
## Hash Tables
|
||||||
|
|
||||||
|
A [struct@GLib.HashTable] provides associations between keys and values which is
|
||||||
|
optimized so that given a key, the associated value can be found, inserted or removed
|
||||||
|
in amortized O(1). All operations going through each element take O(n) time (list all
|
||||||
|
keys/values, table resize, etc.).
|
||||||
|
|
||||||
|
Note that neither keys nor values are copied when inserted into the `GHashTable`,
|
||||||
|
so they must exist for the lifetime of the `GHashTable`. This means that the use
|
||||||
|
of static strings is OK, but temporary strings (i.e. those created in buffers and those
|
||||||
|
returned by GTK widgets) should be copied with [func@GLib.strdup] before being inserted.
|
||||||
|
|
||||||
|
If keys or values are dynamically allocated, you must be careful to ensure that they are freed
|
||||||
|
when they are removed from the `GHashTable`, and also when they are overwritten by
|
||||||
|
new insertions into the `GHashTable`. It is also not advisable to mix static strings
|
||||||
|
and dynamically-allocated strings in a [struct@GLib.HashTable], because it then becomes difficult
|
||||||
|
to determine whether the string should be freed.
|
||||||
|
|
||||||
|
To create a `GHashTable`, use [func@GLib.HashTable.new].
|
||||||
|
|
||||||
|
To insert a key and value into a `GHashTable`, use [func@GLib.HashTable.insert].
|
||||||
|
|
||||||
|
To look up a value corresponding to a given key, use [func@GLib.HashTable.lookup] or
|
||||||
|
[func@GLib.HashTable.lookup_extended].
|
||||||
|
|
||||||
|
[func@GLib.HashTable.lookup_extended] can also be used to simply check if a key is present
|
||||||
|
in the hash table.
|
||||||
|
|
||||||
|
To remove a key and value, use [func@GLib.HashTable.remove].
|
||||||
|
|
||||||
|
To call a function for each key and value pair use [func@GLib.HashTable.foreach] or use
|
||||||
|
an iterator to iterate over the key/value pairs in the hash table, see [struct@GLib.HashTableIter].
|
||||||
|
The iteration order of a hash table is not defined, and you must not rely on iterating over
|
||||||
|
keys/values in the same order as they were inserted.
|
||||||
|
|
||||||
|
To destroy a `GHashTable` use [func@GLib.HashTable.unref] or [func@GLib.HashTable.destroy].
|
||||||
|
|
||||||
|
A common use-case for hash tables is to store information about a set of keys, without associating any
|
||||||
|
particular value with each key. `GHashTable` optimizes one way of doing so: If you store only
|
||||||
|
key-value pairs where key == value, then `GHashTable` does not allocate memory to store the values,
|
||||||
|
which can be a considerable space saving, if your set is large. The functions [func@GLib.HashTable.add]
|
||||||
|
and [func@GLib.HashTable.contains] are designed to be used when using `GHashTable` this way.
|
||||||
|
|
||||||
|
`GHashTable` is not designed to be statically initialised with keys and values known at compile time.
|
||||||
|
To build a static hash table, use a tool such as [gperf](https://www.gnu.org/software/gperf/).
|
||||||
|
|
||||||
|
## Double-ended Queues
|
||||||
|
|
||||||
|
The [struct@GLib.Queue] structure and its associated functions provide a standard queue data structure.
|
||||||
|
Internally, `GQueue` uses the same data structure as [struct@GLib.List] to store elements with the same
|
||||||
|
complexity over insertion/deletion (O(1)) and access/search (O(n)) operations.
|
||||||
|
|
||||||
|
The data contained in each element can be either integer values, by using one of the
|
||||||
|
[Type Conversion Macros](conversion-macros.html), or simply pointers to any type of data.
|
||||||
|
|
||||||
|
As with all other GLib data structures, `GQueue` is not thread-safe. For a thread-safe queue, use
|
||||||
|
[struct@GLib.AsyncQueue].
|
||||||
|
|
||||||
|
To create a new GQueue, use [func@GLib.Queue.new].
|
||||||
|
|
||||||
|
To initialize a statically-allocated GQueue, use `G_QUEUE_INIT` or [method@GLib.Queue.init].
|
||||||
|
|
||||||
|
To add elements, use [method@GLib.Queue.push_head], [method@GLib.Queue.push_head_link],
|
||||||
|
[method@GLib.Queue.push_tail] and [method@GLib.Queue.push_tail_link].
|
||||||
|
|
||||||
|
To remove elements, use [method@GLib.Queue.pop_head] and [method@GLib.Queue.pop_tail].
|
||||||
|
|
||||||
|
To free the entire queue, use [method@GLib.Queue.free].
|
||||||
|
|
||||||
|
## Asynchronous Queues
|
||||||
|
|
||||||
|
Often you need to communicate between different threads. In general it's safer not to do this
|
||||||
|
by shared memory, but by explicit message passing. These messages only make sense asynchronously
|
||||||
|
for multi-threaded applications though, as a synchronous operation could as well be done in the
|
||||||
|
same thread.
|
||||||
|
|
||||||
|
Asynchronous queues are an exception from most other GLib data structures, as they can be used
|
||||||
|
simultaneously from multiple threads without explicit locking and they bring their own builtin
|
||||||
|
reference counting. This is because the nature of an asynchronous queue is that it will always
|
||||||
|
be used by at least 2 concurrent threads.
|
||||||
|
|
||||||
|
For using an asynchronous queue you first have to create one with [func@GLib.AsyncQueue.new].
|
||||||
|
[struct@GLib.AsyncQueue] structs are reference counted, use [method@GLib.AsyncQueue.ref] and
|
||||||
|
[method@GLib.AsyncQueue.unref] to manage your references.
|
||||||
|
|
||||||
|
A thread which wants to send a message to that queue simply calls [method@GLib.AsyncQueue.push]
|
||||||
|
to push the message to the queue.
|
||||||
|
|
||||||
|
A thread which is expecting messages from an asynchronous queue simply calls [method@GLib.AsyncQueue.pop]
|
||||||
|
for that queue. If no message is available in the queue at that point, the thread is now put to sleep
|
||||||
|
until a message arrives. The message will be removed from the queue and returned. The functions
|
||||||
|
[method@GLib.AsyncQueue.try_pop] and [method@GLib.AsyncQueue.timeout_pop] can be used to only check
|
||||||
|
for the presence of messages or to only wait a certain time for messages respectively.
|
||||||
|
|
||||||
|
For almost every function there exist two variants, one that locks the queue and one that doesn't.
|
||||||
|
That way you can hold the queue lock (acquire it with [method@GLib.AsyncQueue.lock] and release it
|
||||||
|
with [method@GLib.AsyncQueue.unlock] over multiple queue accessing instructions. This can be necessary
|
||||||
|
to ensure the integrity of the queue, but should only be used when really necessary, as it can make your
|
||||||
|
life harder if used unwisely. Normally you should only use the locking function variants (those without
|
||||||
|
the `_unlocked` suffix).
|
||||||
|
|
||||||
|
In many cases, it may be more convenient to use [struct@GLib.ThreadPool] when you need to distribute work
|
||||||
|
to a set of worker threads instead of using `GAsyncQueue` manually. `GThreadPool` uses a `GAsyncQueue`
|
||||||
|
internally.
|
||||||
|
|
||||||
|
## Binary Trees
|
||||||
|
|
||||||
|
The [struct@GLib.Tree] structure and its associated functions provide a sorted collection of key/value
|
||||||
|
pairs optimized for searching and traversing in order. This means that most of the operations (access,
|
||||||
|
search, insertion, deletion, …) on `GTree` are O(log(n)) in average and O(n) in worst case for time
|
||||||
|
complexity. But, note that maintaining a balanced sorted `GTree` of n elements is done in time O(n log(n)).
|
||||||
|
|
||||||
|
To create a new `GTree` use [ctor@GLib.Tree.new].
|
||||||
|
|
||||||
|
To insert a key/value pair into a `GTree` use [method@GLib.Tree.insert] (O(n log(n))).
|
||||||
|
|
||||||
|
To remove a key/value pair use [method@GLib.Tree.remove] (O(n log(n))).
|
||||||
|
|
||||||
|
To look up the value corresponding to a given key, use [method@GLib.Tree.lookup] and
|
||||||
|
[method@GLib.Tree.lookup_extended].
|
||||||
|
|
||||||
|
To find out the number of nodes in a `GTree`, use [method@GLib.Tree.nnodes].
|
||||||
|
To get the height of a `GTree`, use [method@GLib.Tree.height].
|
||||||
|
|
||||||
|
To traverse a `GTree`, calling a function for each node visited in
|
||||||
|
the traversal, use [method@GLib.Tree.foreach].
|
||||||
|
|
||||||
|
To destroy a `GTree`, use [method@GLib.Tree.destroy].
|
||||||
|
|
||||||
|
## N-ary Trees
|
||||||
|
|
||||||
|
The [struct@GLib.Node] struct and its associated functions provide a N-ary tree
|
||||||
|
data structure, where nodes in the tree can contain arbitrary data.
|
||||||
|
|
||||||
|
To create a new tree use [func@GLib.Node.new].
|
||||||
|
|
||||||
|
To insert a node into a tree use [method@GLib.Node.insert], [method@GLib.Node.insert_before],
|
||||||
|
[func@GLib.node_append] and [method@GLib.Node.prepend],
|
||||||
|
|
||||||
|
To create a new node and insert it into a tree use [func@GLib.node_insert_data],
|
||||||
|
[func@GLib.node_insert_data_after], [func@GLib.node_insert_data_before],
|
||||||
|
[func@GLib.node_append_data] and [func@GLib.node_prepend_data].
|
||||||
|
|
||||||
|
To reverse the children of a node use [method@GLib.Node.reverse_children].
|
||||||
|
|
||||||
|
To find a node use [method@GLib.Node.get_root], [method@GLib.Node.find], [method@GLib.Node.find_child],
|
||||||
|
[method@GLib.Node.child_index], [method@GLib.Node.child_position], [func@GLib.node_first_child],
|
||||||
|
[method@GLib.Node.last_child], [method@GLib.Node.nth_child], [method@GLib.Node.first_sibling],
|
||||||
|
[func@GLib.node_prev_sibling], [func@GLib.node_next_sibling] or [method@GLib.Node.last_sibling].
|
||||||
|
|
||||||
|
To get information about a node or tree use `G_NODE_IS_LEAF()`,
|
||||||
|
`G_NODE_IS_ROOT()`, [method@GLib.Node.depth], [method@GLib.Node.n_nodes],
|
||||||
|
[method@GLib.Node.n_children], [method@GLib.Node.is_ancestor] or [method@GLib.Node.max_height].
|
||||||
|
|
||||||
|
To traverse a tree, calling a function for each node visited in the traversal, use
|
||||||
|
[method@GLib.Node.traverse] or [method@GLib.Node.children_foreach].
|
||||||
|
|
||||||
|
To remove a node or subtree from a tree use [method@GLib.Node.unlink] or [method@GLib.Node.destroy].
|
||||||
|
|
||||||
|
## Scalable Lists
|
||||||
|
|
||||||
|
The [struct@GLib.Sequence] data structure has the API of a list, but is implemented internally with
|
||||||
|
a balanced binary tree. This means that most of the operations (access, search, insertion, deletion,
|
||||||
|
...) on `GSequence` are O(log(n)) in average and O(n) in worst case for time complexity. But, note that
|
||||||
|
maintaining a balanced sorted list of n elements is done in time O(n log(n)). The data contained
|
||||||
|
in each element can be either integer values, by using of the
|
||||||
|
[Type Conversion Macros](conversion-macros.md), or simply pointers to any type of data.
|
||||||
|
|
||||||
|
A `GSequence` is accessed through "iterators", represented by a [struct@GLib.SequenceIter]. An iterator
|
||||||
|
represents a position between two elements of the sequence. For example, the "begin" iterator represents
|
||||||
|
the gap immediately before the first element of the sequence, and the "end" iterator represents the gap
|
||||||
|
immediately after the last element. In an empty sequence, the begin and end iterators are the same.
|
||||||
|
|
||||||
|
Some methods on `GSequence` operate on ranges of items. For example [func@GLib.Sequence.foreach_range]
|
||||||
|
will call a user-specified function on each element with the given range. The range is delimited by the
|
||||||
|
gaps represented by the passed-in iterators, so if you pass in the begin and end iterators, the range in
|
||||||
|
question is the entire sequence.
|
||||||
|
|
||||||
|
The function [func@GLib.Sequence.get] is used with an iterator to access the element immediately following
|
||||||
|
the gap that the iterator represents. The iterator is said to "point" to that element.
|
||||||
|
|
||||||
|
Iterators are stable across most operations on a `GSequence`. For example an iterator pointing to some element
|
||||||
|
of a sequence will continue to point to that element even after the sequence is sorted. Even moving an element
|
||||||
|
to another sequence using for example [func@GLib.Sequence.move_range] will not invalidate the iterators pointing
|
||||||
|
to it. The only operation that will invalidate an iterator is when the element it points to is removed from
|
||||||
|
any sequence.
|
||||||
|
|
||||||
|
To sort the data, either use [method@GLib.Sequence.insert_sorted] or [method@GLib.Sequence.insert_sorted_iter]
|
||||||
|
to add data to the `GSequence` or, if you want to add a large amount of data, it is more efficient to call
|
||||||
|
[method@GLib.Sequence.sort] or [method@GLib.Sequence.sort_iter] after doing unsorted insertions.
|
||||||
|
|
||||||
|
## Reference-counted strings
|
||||||
|
|
||||||
|
Reference-counted strings are normal C strings that have been augmented with a reference count to manage
|
||||||
|
their resources. You allocate a new reference counted string and acquire and release references as needed,
|
||||||
|
instead of copying the string among callers; when the last reference on the string is released, the resources
|
||||||
|
allocated for it are freed.
|
||||||
|
|
||||||
|
Typically, reference-counted strings can be used when parsing data from files and storing them into data
|
||||||
|
structures that are passed to various callers:
|
||||||
|
|
||||||
|
```c
|
||||||
|
PersonDetails *
|
||||||
|
person_details_from_data (const char *data)
|
||||||
|
{
|
||||||
|
// Use g_autoptr() to simplify error cases
|
||||||
|
g_autoptr(GRefString) full_name = NULL;
|
||||||
|
g_autoptr(GRefString) address = NULL;
|
||||||
|
g_autoptr(GRefString) city = NULL;
|
||||||
|
g_autoptr(GRefString) state = NULL;
|
||||||
|
g_autoptr(GRefString) zip_code = NULL;
|
||||||
|
|
||||||
|
// parse_person_details() is defined elsewhere; returns refcounted strings
|
||||||
|
if (!parse_person_details (data, &full_name, &address, &city, &state, &zip_code))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!validate_zip_code (zip_code))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// add_address_to_cache() and add_full_name_to_cache() are defined
|
||||||
|
// elsewhere; they add strings to various caches, using refcounted
|
||||||
|
// strings to avoid copying data over and over again
|
||||||
|
add_address_to_cache (address, city, state, zip_code);
|
||||||
|
add_full_name_to_cache (full_name);
|
||||||
|
|
||||||
|
// person_details_new() is defined elsewhere; it takes a reference
|
||||||
|
// on each string
|
||||||
|
PersonDetails *res = person_details_new (full_name,
|
||||||
|
address,
|
||||||
|
city,
|
||||||
|
state,
|
||||||
|
zip_code);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In the example above, we have multiple functions taking the same strings for different uses; with typical
|
||||||
|
C strings, we'd have to copy the strings every time the life time rules of the data differ from the
|
||||||
|
life-time of the string parsed from the original buffer. With reference counted strings, each caller can
|
||||||
|
ake a reference on the data, and keep it as long as it needs to own the string.
|
||||||
|
|
||||||
|
Reference-counted strings can also be "interned" inside a global table owned by GLib; while an interned
|
||||||
|
string has at least a reference, creating a new interned reference-counted string with the same contents
|
||||||
|
will return a reference to the existing string instead of creating a new reference-counted string instance.
|
||||||
|
Once the string loses its last reference, it will be automatically removed from the global interned strings
|
||||||
|
table.
|
||||||
|
|
||||||
|
Reference-counted strings were added to GLib in 2.58.
|
@ -64,6 +64,8 @@ content_files = [
|
|||||||
"threads.md",
|
"threads.md",
|
||||||
"markup.md",
|
"markup.md",
|
||||||
"goption.md",
|
"goption.md",
|
||||||
|
"data-structures.md",
|
||||||
|
"unicode.md",
|
||||||
]
|
]
|
||||||
content_images = [
|
content_images = [
|
||||||
"file-name-encodings.png",
|
"file-name-encodings.png",
|
||||||
|
@ -162,6 +162,8 @@ expand_content_files = [
|
|||||||
'threads.md',
|
'threads.md',
|
||||||
'markup.md',
|
'markup.md',
|
||||||
'goption.md',
|
'goption.md',
|
||||||
|
'data-structures.md',
|
||||||
|
'unicode.md',
|
||||||
]
|
]
|
||||||
|
|
||||||
glib_gir = meson.current_source_dir() / 'GLib-2.0.gir'
|
glib_gir = meson.current_source_dir() / 'GLib-2.0.gir'
|
||||||
|
37
docs/reference/glib/unicode.md
Normal file
37
docs/reference/glib/unicode.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
Title: Unicode
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
SPDX-FileCopyrightText: 2011, 2014, 2023 Matthias Clasen
|
||||||
|
SPDX-FileCopyrightText: 2020 Endless OS Foundation, LLC
|
||||||
|
|
||||||
|
# Unicode support
|
||||||
|
|
||||||
|
GLib has support for various aspects of Unicode, and provides a number of APIs for dealing
|
||||||
|
with Unicode characters and strings.
|
||||||
|
|
||||||
|
There are analogues of the traditional `ctype.h` character classification and case conversion
|
||||||
|
functions, UTF-8 analogues of some string utility functions, functions to perform normalization,
|
||||||
|
case conversion and collation on UTF-8 strings and finally functions to convert between the UTF-8,
|
||||||
|
UTF-16 and UCS-4 encodings of Unicode.
|
||||||
|
|
||||||
|
The implementations of the Unicode functions in GLib are based on the Unicode Character Data tables,
|
||||||
|
which are available from [www.unicode.org](http://www.unicode.org/).
|
||||||
|
|
||||||
|
- Unicode 4.0 was added in GLib 2.8
|
||||||
|
- Unicode 4.1 was added in GLib 2.10
|
||||||
|
- Unicode 5.0 was added in GLib 2.12
|
||||||
|
- Unicode 5.1 was added in GLib 2.16.3
|
||||||
|
- Unicode 6.0 was added in GLib 2.30
|
||||||
|
- Unicode 6.1 was added in GLib 2.32
|
||||||
|
- Unicode 6.2 was added in GLib 2.36
|
||||||
|
- Unicode 6.3 was added in GLib 2.40
|
||||||
|
- Unicode 7.0 was added in GLib 2.42
|
||||||
|
- Unicode 8.0 was added in GLib 2.48
|
||||||
|
- Unicode 9.0 was added in GLib 2.50.1
|
||||||
|
- Unicode 10.0 was added in GLib 2.54
|
||||||
|
- Unicode 11.10 was added in GLib 2.58
|
||||||
|
- Unicode 12.0 was added in GLib 2.62
|
||||||
|
- Unicode 12.1 was added in GLib 2.62
|
||||||
|
- Unicode 13.0 was added in GLib 2.66
|
||||||
|
- Unicode 14.0 was added in GLib 2.71
|
||||||
|
- Unicode 15.0 was added in GLib 2.76
|
||||||
|
|
134
glib/garray.c
134
glib/garray.c
@ -47,53 +47,6 @@
|
|||||||
#include "grefcount.h"
|
#include "grefcount.h"
|
||||||
#include "gutilsprivate.h"
|
#include "gutilsprivate.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:arrays
|
|
||||||
* @title: Arrays
|
|
||||||
* @short_description: arrays of arbitrary elements which grow
|
|
||||||
* automatically as elements are added
|
|
||||||
*
|
|
||||||
* Arrays are similar to standard C arrays, except that they grow
|
|
||||||
* automatically as elements are added.
|
|
||||||
*
|
|
||||||
* Array elements can be of any size (though all elements of one array
|
|
||||||
* are the same size), and the array can be automatically cleared to
|
|
||||||
* '0's and zero-terminated.
|
|
||||||
*
|
|
||||||
* To create a new array use g_array_new().
|
|
||||||
*
|
|
||||||
* To add elements to an array with a cost of O(n) at worst, use
|
|
||||||
* g_array_append_val(), g_array_append_vals(), g_array_prepend_val(),
|
|
||||||
* g_array_prepend_vals(), g_array_insert_val() and g_array_insert_vals().
|
|
||||||
*
|
|
||||||
* To access an element of an array in O(1) (to read it or to write it),
|
|
||||||
* use g_array_index().
|
|
||||||
*
|
|
||||||
* To set the size of an array, use g_array_set_size().
|
|
||||||
*
|
|
||||||
* To free an array, use g_array_unref() or g_array_free().
|
|
||||||
*
|
|
||||||
* All the sort functions are internally calling a quick-sort (or similar)
|
|
||||||
* function with an average cost of O(n log(n)) and a worst case
|
|
||||||
* cost of O(n^2).
|
|
||||||
*
|
|
||||||
* Here is an example that stores integers in a #GArray:
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* GArray *garray;
|
|
||||||
* gint i;
|
|
||||||
* // We create a new array to store gint values.
|
|
||||||
* // We don't want it zero-terminated or cleared to 0's.
|
|
||||||
* garray = g_array_new (FALSE, FALSE, sizeof (gint));
|
|
||||||
* for (i = 0; i < 10000; i++)
|
|
||||||
* g_array_append_val (garray, i);
|
|
||||||
* for (i = 0; i < 10000; i++)
|
|
||||||
* if (g_array_index (garray, gint, i) != i)
|
|
||||||
* g_print ("ERROR: got %d instead of %d\n",
|
|
||||||
* g_array_index (garray, gint, i), i);
|
|
||||||
* g_array_free (garray, TRUE);
|
|
||||||
* ]|
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MIN_ARRAY_SIZE 16
|
#define MIN_ARRAY_SIZE 16
|
||||||
|
|
||||||
typedef struct _GRealArray GRealArray;
|
typedef struct _GRealArray GRealArray;
|
||||||
@ -1126,54 +1079,6 @@ g_array_maybe_expand (GRealArray *array,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:arrays_pointer
|
|
||||||
* @title: Pointer Arrays
|
|
||||||
* @short_description: arrays of pointers to any type of data, which
|
|
||||||
* grow automatically as new elements are added
|
|
||||||
*
|
|
||||||
* Pointer Arrays are similar to Arrays but are used only for storing
|
|
||||||
* pointers.
|
|
||||||
*
|
|
||||||
* If you remove elements from the array, elements at the end of the
|
|
||||||
* array are moved into the space previously occupied by the removed
|
|
||||||
* element. This means that you should not rely on the index of particular
|
|
||||||
* elements remaining the same. You should also be careful when deleting
|
|
||||||
* elements while iterating over the array.
|
|
||||||
*
|
|
||||||
* To create a pointer array, use g_ptr_array_new().
|
|
||||||
*
|
|
||||||
* To add elements to a pointer array, use g_ptr_array_add().
|
|
||||||
*
|
|
||||||
* To remove elements from a pointer array, use g_ptr_array_remove(),
|
|
||||||
* g_ptr_array_remove_index() or g_ptr_array_remove_index_fast().
|
|
||||||
*
|
|
||||||
* To access an element of a pointer array, use g_ptr_array_index().
|
|
||||||
*
|
|
||||||
* To set the size of a pointer array, use g_ptr_array_set_size().
|
|
||||||
*
|
|
||||||
* To free a pointer array, use g_ptr_array_free().
|
|
||||||
*
|
|
||||||
* An example using a #GPtrArray:
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* GPtrArray *array;
|
|
||||||
* gchar *string1 = "one";
|
|
||||||
* gchar *string2 = "two";
|
|
||||||
* gchar *string3 = "three";
|
|
||||||
*
|
|
||||||
* array = g_ptr_array_new ();
|
|
||||||
* g_ptr_array_add (array, (gpointer) string1);
|
|
||||||
* g_ptr_array_add (array, (gpointer) string2);
|
|
||||||
* g_ptr_array_add (array, (gpointer) string3);
|
|
||||||
*
|
|
||||||
* if (g_ptr_array_index (array, 0) != (gpointer) string1)
|
|
||||||
* g_print ("ERROR: got %p instead of %p\n",
|
|
||||||
* g_ptr_array_index (array, 0), string1);
|
|
||||||
*
|
|
||||||
* g_ptr_array_free (array, TRUE);
|
|
||||||
* ]|
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct _GRealPtrArray GRealPtrArray;
|
typedef struct _GRealPtrArray GRealPtrArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2765,45 +2670,6 @@ g_ptr_array_find_with_equal_func (GPtrArray *haystack,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:arrays_byte
|
|
||||||
* @title: Byte Arrays
|
|
||||||
* @short_description: arrays of bytes
|
|
||||||
*
|
|
||||||
* #GByteArray is a mutable array of bytes based on #GArray, to provide arrays
|
|
||||||
* of bytes which grow automatically as elements are added.
|
|
||||||
*
|
|
||||||
* To create a new #GByteArray use g_byte_array_new(). To add elements to a
|
|
||||||
* #GByteArray, use g_byte_array_append(), and g_byte_array_prepend().
|
|
||||||
*
|
|
||||||
* To set the size of a #GByteArray, use g_byte_array_set_size().
|
|
||||||
*
|
|
||||||
* To free a #GByteArray, use g_byte_array_free().
|
|
||||||
*
|
|
||||||
* An example for using a #GByteArray:
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* GByteArray *gbarray;
|
|
||||||
* gint i;
|
|
||||||
*
|
|
||||||
* gbarray = g_byte_array_new ();
|
|
||||||
* for (i = 0; i < 10000; i++)
|
|
||||||
* g_byte_array_append (gbarray, (guint8*) "abcd", 4);
|
|
||||||
*
|
|
||||||
* for (i = 0; i < 10000; i++)
|
|
||||||
* {
|
|
||||||
* g_assert (gbarray->data[4*i] == 'a');
|
|
||||||
* g_assert (gbarray->data[4*i+1] == 'b');
|
|
||||||
* g_assert (gbarray->data[4*i+2] == 'c');
|
|
||||||
* g_assert (gbarray->data[4*i+3] == 'd');
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* g_byte_array_free (gbarray, TRUE);
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* See #GBytes if you are interested in an immutable object representing a
|
|
||||||
* sequence of bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GByteArray:
|
* GByteArray:
|
||||||
* @data: a pointer to the element data. The data may be moved as
|
* @data: a pointer to the element data. The data may be moved as
|
||||||
|
@ -37,56 +37,6 @@
|
|||||||
#include "gthread.h"
|
#include "gthread.h"
|
||||||
#include "deprecated/gthread.h"
|
#include "deprecated/gthread.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:async_queues
|
|
||||||
* @title: Asynchronous Queues
|
|
||||||
* @short_description: asynchronous communication between threads
|
|
||||||
* @see_also: #GThreadPool
|
|
||||||
*
|
|
||||||
* Often you need to communicate between different threads. In general
|
|
||||||
* it's safer not to do this by shared memory, but by explicit message
|
|
||||||
* passing. These messages only make sense asynchronously for
|
|
||||||
* multi-threaded applications though, as a synchronous operation could
|
|
||||||
* as well be done in the same thread.
|
|
||||||
*
|
|
||||||
* Asynchronous queues are an exception from most other GLib data
|
|
||||||
* structures, as they can be used simultaneously from multiple threads
|
|
||||||
* without explicit locking and they bring their own builtin reference
|
|
||||||
* counting. This is because the nature of an asynchronous queue is that
|
|
||||||
* it will always be used by at least 2 concurrent threads.
|
|
||||||
*
|
|
||||||
* For using an asynchronous queue you first have to create one with
|
|
||||||
* g_async_queue_new(). #GAsyncQueue structs are reference counted,
|
|
||||||
* use g_async_queue_ref() and g_async_queue_unref() to manage your
|
|
||||||
* references.
|
|
||||||
*
|
|
||||||
* A thread which wants to send a message to that queue simply calls
|
|
||||||
* g_async_queue_push() to push the message to the queue.
|
|
||||||
*
|
|
||||||
* A thread which is expecting messages from an asynchronous queue
|
|
||||||
* simply calls g_async_queue_pop() for that queue. If no message is
|
|
||||||
* available in the queue at that point, the thread is now put to sleep
|
|
||||||
* until a message arrives. The message will be removed from the queue
|
|
||||||
* and returned. The functions g_async_queue_try_pop() and
|
|
||||||
* g_async_queue_timeout_pop() can be used to only check for the presence
|
|
||||||
* of messages or to only wait a certain time for messages respectively.
|
|
||||||
*
|
|
||||||
* For almost every function there exist two variants, one that locks
|
|
||||||
* the queue and one that doesn't. That way you can hold the queue lock
|
|
||||||
* (acquire it with g_async_queue_lock() and release it with
|
|
||||||
* g_async_queue_unlock()) over multiple queue accessing instructions.
|
|
||||||
* This can be necessary to ensure the integrity of the queue, but should
|
|
||||||
* only be used when really necessary, as it can make your life harder
|
|
||||||
* if used unwisely. Normally you should only use the locking function
|
|
||||||
* variants (those without the _unlocked suffix).
|
|
||||||
*
|
|
||||||
* In many cases, it may be more convenient to use #GThreadPool when
|
|
||||||
* you need to distribute work to a set of worker threads instead of
|
|
||||||
* using #GAsyncQueue manually. #GThreadPool uses a GAsyncQueue
|
|
||||||
* internally.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GAsyncQueue:
|
* GAsyncQueue:
|
||||||
*
|
*
|
||||||
|
@ -52,51 +52,6 @@
|
|||||||
#include "gutils.h"
|
#include "gutils.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:gbookmarkfile
|
|
||||||
* @title: Bookmark file parser
|
|
||||||
* @short_description: parses files containing bookmarks
|
|
||||||
*
|
|
||||||
* GBookmarkFile lets you parse, edit or create files containing bookmarks
|
|
||||||
* to URI, along with some meta-data about the resource pointed by the URI
|
|
||||||
* like its MIME type, the application that is registering the bookmark and
|
|
||||||
* the icon that should be used to represent the bookmark. The data is stored
|
|
||||||
* using the
|
|
||||||
* [Desktop Bookmark Specification](http://www.gnome.org/~ebassi/bookmark-spec).
|
|
||||||
*
|
|
||||||
* The syntax of the bookmark files is described in detail inside the
|
|
||||||
* Desktop Bookmark Specification, here is a quick summary: bookmark
|
|
||||||
* files use a sub-class of the XML Bookmark Exchange Language
|
|
||||||
* specification, consisting of valid UTF-8 encoded XML, under the
|
|
||||||
* <xbel> root element; each bookmark is stored inside a
|
|
||||||
* <bookmark> element, using its URI: no relative paths can
|
|
||||||
* be used inside a bookmark file. The bookmark may have a user defined
|
|
||||||
* title and description, to be used instead of the URI. Under the
|
|
||||||
* <metadata> element, with its owner attribute set to
|
|
||||||
* `http://freedesktop.org`, is stored the meta-data about a resource
|
|
||||||
* pointed by its URI. The meta-data consists of the resource's MIME
|
|
||||||
* type; the applications that have registered a bookmark; the groups
|
|
||||||
* to which a bookmark belongs to; a visibility flag, used to set the
|
|
||||||
* bookmark as "private" to the applications and groups that has it
|
|
||||||
* registered; the URI and MIME type of an icon, to be used when
|
|
||||||
* displaying the bookmark inside a GUI.
|
|
||||||
*
|
|
||||||
* Here is an example of a bookmark file:
|
|
||||||
* [bookmarks.xbel](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/glib/tests/bookmarks.xbel)
|
|
||||||
*
|
|
||||||
* A bookmark file might contain more than one bookmark; each bookmark
|
|
||||||
* is accessed through its URI.
|
|
||||||
*
|
|
||||||
* The important caveat of bookmark files is that when you add a new
|
|
||||||
* bookmark you must also add the application that is registering it, using
|
|
||||||
* g_bookmark_file_add_application() or g_bookmark_file_set_application_info().
|
|
||||||
* If a bookmark has no applications then it won't be dumped when creating
|
|
||||||
* the on disk representation, using g_bookmark_file_to_data() or
|
|
||||||
* g_bookmark_file_to_file().
|
|
||||||
*
|
|
||||||
* The #GBookmarkFile parser was added in GLib 2.12.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XBEL 1.0 standard entities */
|
/* XBEL 1.0 standard entities */
|
||||||
#define XBEL_VERSION "1.0"
|
#define XBEL_VERSION "1.0"
|
||||||
#define XBEL_DTD_NICK "xbel"
|
#define XBEL_DTD_NICK "xbel"
|
||||||
|
@ -75,7 +75,45 @@ GQuark g_bookmark_file_error_quark (void);
|
|||||||
/**
|
/**
|
||||||
* GBookmarkFile:
|
* GBookmarkFile:
|
||||||
*
|
*
|
||||||
* An opaque data structure representing a set of bookmarks.
|
* `GBookmarkFile` lets you parse, edit or create files containing bookmarks.
|
||||||
|
*
|
||||||
|
* Bookmarks refer to a URI, along with some meta-data about the resource
|
||||||
|
* pointed by the URI like its MIME type, the application that is registering
|
||||||
|
* the bookmark and the icon that should be used to represent the bookmark.
|
||||||
|
* The data is stored using the
|
||||||
|
* [Desktop Bookmark Specification](http://www.gnome.org/~ebassi/bookmark-spec).
|
||||||
|
*
|
||||||
|
* The syntax of the bookmark files is described in detail inside the
|
||||||
|
* Desktop Bookmark Specification, here is a quick summary: bookmark
|
||||||
|
* files use a sub-class of the XML Bookmark Exchange Language
|
||||||
|
* specification, consisting of valid UTF-8 encoded XML, under the
|
||||||
|
* `<xbel>` root element; each bookmark is stored inside a
|
||||||
|
* `<bookmark>` element, using its URI: no relative paths can
|
||||||
|
* be used inside a bookmark file. The bookmark may have a user defined
|
||||||
|
* title and description, to be used instead of the URI. Under the
|
||||||
|
* `<metadata>` element, with its owner attribute set to
|
||||||
|
* `http://freedesktop.org`, is stored the meta-data about a resource
|
||||||
|
* pointed by its URI. The meta-data consists of the resource's MIME
|
||||||
|
* type; the applications that have registered a bookmark; the groups
|
||||||
|
* to which a bookmark belongs to; a visibility flag, used to set the
|
||||||
|
* bookmark as "private" to the applications and groups that has it
|
||||||
|
* registered; the URI and MIME type of an icon, to be used when
|
||||||
|
* displaying the bookmark inside a GUI.
|
||||||
|
*
|
||||||
|
* Here is an example of a bookmark file:
|
||||||
|
* [bookmarks.xbel](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/glib/tests/bookmarks.xbel)
|
||||||
|
*
|
||||||
|
* A bookmark file might contain more than one bookmark; each bookmark
|
||||||
|
* is accessed through its URI.
|
||||||
|
*
|
||||||
|
* The important caveat of bookmark files is that when you add a new
|
||||||
|
* bookmark you must also add the application that is registering it, using
|
||||||
|
* [method@GLib.BookmarkFile.add_application] or [method@GLib.BookmarkFile.set_application_info].
|
||||||
|
* If a bookmark has no applications then it won't be dumped when creating
|
||||||
|
* the on disk representation, using [method@GLib.BookmarkFile.to_data] or
|
||||||
|
* [method@GLib.BookmarkFile.to_file].
|
||||||
|
*
|
||||||
|
* Since: 2.12
|
||||||
*/
|
*/
|
||||||
typedef struct _GBookmarkFile GBookmarkFile;
|
typedef struct _GBookmarkFile GBookmarkFile;
|
||||||
|
|
||||||
|
48
glib/gdate.c
48
glib/gdate.c
@ -60,21 +60,21 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:date
|
* GDate:
|
||||||
* @title: Date and Time Functions
|
|
||||||
* @short_description: calendrical calculations and miscellaneous time stuff
|
|
||||||
*
|
*
|
||||||
* The #GDate data structure represents a day between January 1, Year 1,
|
* `GDate` is a struct for calendrical calculations.
|
||||||
|
*
|
||||||
|
* The `GDate` data structure represents a day between January 1, Year 1,
|
||||||
* and sometime a few thousand years in the future (right now it will go
|
* and sometime a few thousand years in the future (right now it will go
|
||||||
* to the year 65535 or so, but g_date_set_parse() only parses up to the
|
* to the year 65535 or so, but [method@GLib.Date.set_parse] only parses up to the
|
||||||
* year 8000 or so - just count on "a few thousand"). #GDate is meant to
|
* year 8000 or so - just count on "a few thousand"). `GDate` is meant to
|
||||||
* represent everyday dates, not astronomical dates or historical dates
|
* represent everyday dates, not astronomical dates or historical dates
|
||||||
* or ISO timestamps or the like. It extrapolates the current Gregorian
|
* or ISO timestamps or the like. It extrapolates the current Gregorian
|
||||||
* calendar forward and backward in time; there is no attempt to change
|
* calendar forward and backward in time; there is no attempt to change
|
||||||
* the calendar to match time periods or locations. #GDate does not store
|
* the calendar to match time periods or locations. `GDate` does not store
|
||||||
* time information; it represents a day.
|
* time information; it represents a day.
|
||||||
*
|
*
|
||||||
* The #GDate implementation has several nice features; it is only a
|
* The `GDate` implementation has several nice features; it is only a
|
||||||
* 64-bit struct, so storing large numbers of dates is very efficient. It
|
* 64-bit struct, so storing large numbers of dates is very efficient. It
|
||||||
* can keep both a Julian and day-month-year representation of the date,
|
* can keep both a Julian and day-month-year representation of the date,
|
||||||
* since some calculations are much easier with one representation or the
|
* since some calculations are much easier with one representation or the
|
||||||
@ -84,25 +84,23 @@
|
|||||||
* technical sense; technically, Julian dates count from the start of the
|
* technical sense; technically, Julian dates count from the start of the
|
||||||
* Julian period, Jan 1, 4713 BC).
|
* Julian period, Jan 1, 4713 BC).
|
||||||
*
|
*
|
||||||
* #GDate is simple to use. First you need a "blank" date; you can get a
|
* `GDate` is simple to use. First you need a "blank" date; you can get a
|
||||||
* dynamically allocated date from g_date_new(), or you can declare an
|
* dynamically allocated date from [method@GLib.Date.new], or you can declare an
|
||||||
* automatic variable or array and initialize it by
|
* automatic variable or array and initialize it by calling [method@GLib.Date.clear].
|
||||||
* calling g_date_clear(). A cleared date is safe; it's safe to call
|
* A cleared date is safe; it's safe to call [method@GLib.Date.set_dmy] and the other
|
||||||
* g_date_set_dmy() and the other mutator functions to initialize the
|
* mutator functions to initialize the value of a cleared date. However, a cleared date
|
||||||
* value of a cleared date. However, a cleared date is initially
|
* is initially invalid, meaning that it doesn't represent a day that exists.
|
||||||
* invalid, meaning that it doesn't represent a day that exists.
|
* It is undefined to call any of the date calculation routines on an invalid date.
|
||||||
* It is undefined to call any of the date calculation routines on an
|
* If you obtain a date from a user or other unpredictable source, you should check
|
||||||
* invalid date. If you obtain a date from a user or other
|
* its validity with the [method@GLib.Date.valid] predicate. [method@GLib.Date.valid]
|
||||||
* unpredictable source, you should check its validity with the
|
* is also used to check for errors with [method@GLib.Date.set_parse] and other functions
|
||||||
* g_date_valid() predicate. g_date_valid() is also used to check for
|
* that can fail. Dates can be invalidated by calling [method@GLib.Date.clear] again.
|
||||||
* errors with g_date_set_parse() and other functions that can
|
|
||||||
* fail. Dates can be invalidated by calling g_date_clear() again.
|
|
||||||
*
|
*
|
||||||
* It is very important to use the API to access the #GDate
|
* It is very important to use the API to access the `GDate` struct. Often only the
|
||||||
* struct. Often only the day-month-year or only the Julian
|
* day-month-year or only the Julian representation is valid. Sometimes neither is valid.
|
||||||
* representation is valid. Sometimes neither is valid. Use the API.
|
* Use the API.
|
||||||
*
|
*
|
||||||
* GLib also features #GDateTime which represents a precise time.
|
* GLib also features `GDateTime` which represents a precise time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,15 +38,6 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
/* GDate
|
|
||||||
*
|
|
||||||
* Date calculations (not time for now, to be resolved). These are a
|
|
||||||
* mutant combination of Steffen Beyer's DateCalc routines
|
|
||||||
* (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's
|
|
||||||
* date routines (written for in-house software). Written by Havoc
|
|
||||||
* Pennington <hp@pobox.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef gint32 GTime GLIB_DEPRECATED_TYPE_IN_2_62_FOR(GDateTime);
|
typedef gint32 GTime GLIB_DEPRECATED_TYPE_IN_2_62_FOR(GDateTime);
|
||||||
typedef guint16 GDateYear;
|
typedef guint16 GDateYear;
|
||||||
typedef guint8 GDateDay; /* day of the month */
|
typedef guint8 GDateDay; /* day of the month */
|
||||||
|
@ -89,39 +89,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif /* !G_OS_WIN32 */
|
#endif /* !G_OS_WIN32 */
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:date-time
|
|
||||||
* @title: GDateTime
|
|
||||||
* @short_description: a structure representing Date and Time
|
|
||||||
* @see_also: #GTimeZone
|
|
||||||
*
|
|
||||||
* #GDateTime is a structure that combines a Gregorian date and time
|
|
||||||
* into a single structure. It provides many conversion and methods to
|
|
||||||
* manipulate dates and times. Time precision is provided down to
|
|
||||||
* microseconds and the time can range (proleptically) from 0001-01-01
|
|
||||||
* 00:00:00 to 9999-12-31 23:59:59.999999. #GDateTime follows POSIX
|
|
||||||
* time in the sense that it is oblivious to leap seconds.
|
|
||||||
*
|
|
||||||
* #GDateTime is an immutable object; once it has been created it cannot
|
|
||||||
* be modified further. All modifiers will create a new #GDateTime.
|
|
||||||
* Nearly all such functions can fail due to the date or time going out
|
|
||||||
* of range, in which case %NULL will be returned.
|
|
||||||
*
|
|
||||||
* #GDateTime is reference counted: the reference count is increased by calling
|
|
||||||
* g_date_time_ref() and decreased by calling g_date_time_unref(). When the
|
|
||||||
* reference count drops to 0, the resources allocated by the #GDateTime
|
|
||||||
* structure are released.
|
|
||||||
*
|
|
||||||
* Many parts of the API may produce non-obvious results. As an
|
|
||||||
* example, adding two months to January 31st will yield March 31st
|
|
||||||
* whereas adding one month and then one month again will yield either
|
|
||||||
* March 28th or March 29th. Also note that adding 24 hours is not
|
|
||||||
* always the same as adding one day (since days containing daylight
|
|
||||||
* savings time transitions are either 23 or 25 hours in length).
|
|
||||||
*
|
|
||||||
* #GDateTime is available since GLib 2.26.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct _GDateTime
|
struct _GDateTime
|
||||||
{
|
{
|
||||||
/* Microsecond timekeeping within Day */
|
/* Microsecond timekeeping within Day */
|
||||||
|
@ -91,7 +91,31 @@ typedef gint64 GTimeSpan;
|
|||||||
/**
|
/**
|
||||||
* GDateTime:
|
* GDateTime:
|
||||||
*
|
*
|
||||||
* An opaque structure that represents a date and time, including a time zone.
|
* `GDateTime` is a structure that combines a Gregorian date and time
|
||||||
|
* into a single structure.
|
||||||
|
*
|
||||||
|
* `GDateTime` provides many conversion and methods to manipulate dates and times.
|
||||||
|
* Time precision is provided down to microseconds and the time can range
|
||||||
|
* (proleptically) from 0001-01-01 00:00:00 to 9999-12-31 23:59:59.999999.
|
||||||
|
* `GDateTime` follows POSIX time in the sense that it is oblivious to leap
|
||||||
|
* seconds.
|
||||||
|
*
|
||||||
|
* `GDateTime` is an immutable object; once it has been created it cannot
|
||||||
|
* be modified further. All modifiers will create a new `GDateTime`.
|
||||||
|
* Nearly all such functions can fail due to the date or time going out
|
||||||
|
* of range, in which case %NULL will be returned.
|
||||||
|
*
|
||||||
|
* `GDateTime` is reference counted: the reference count is increased by calling
|
||||||
|
* [metohd@GLib.DateTime.ref] and decreased by calling [method@GLib.DateTime.unref].
|
||||||
|
* When the reference count drops to 0, the resources allocated by the `GDateTime`
|
||||||
|
* structure are released.
|
||||||
|
*
|
||||||
|
* Many parts of the API may produce non-obvious results. As an
|
||||||
|
* example, adding two months to January 31st will yield March 31st
|
||||||
|
* whereas adding one month and then one month again will yield either
|
||||||
|
* March 28th or March 29th. Also note that adding 24 hours is not
|
||||||
|
* always the same as adding one day (since days containing daylight
|
||||||
|
* savings time transitions are either 23 or 25 hours in length).
|
||||||
*
|
*
|
||||||
* Since: 2.26
|
* Since: 2.26
|
||||||
*/
|
*/
|
||||||
|
59
glib/ghash.c
59
glib/ghash.c
@ -63,65 +63,6 @@
|
|||||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:hash_tables
|
|
||||||
* @title: Hash Tables
|
|
||||||
* @short_description: associations between keys and values so that
|
|
||||||
* given a key the value can be found quickly
|
|
||||||
*
|
|
||||||
* A #GHashTable provides associations between keys and values which is
|
|
||||||
* optimized so that given a key, the associated value can be found,
|
|
||||||
* inserted or removed in amortized O(1). All operations going through
|
|
||||||
* each element take O(n) time (list all keys/values, table resize, etc.).
|
|
||||||
*
|
|
||||||
* Note that neither keys nor values are copied when inserted into the
|
|
||||||
* #GHashTable, so they must exist for the lifetime of the #GHashTable.
|
|
||||||
* This means that the use of static strings is OK, but temporary
|
|
||||||
* strings (i.e. those created in buffers and those returned by GTK
|
|
||||||
* widgets) should be copied with g_strdup() before being inserted.
|
|
||||||
*
|
|
||||||
* If keys or values are dynamically allocated, you must be careful to
|
|
||||||
* ensure that they are freed when they are removed from the
|
|
||||||
* #GHashTable, and also when they are overwritten by new insertions
|
|
||||||
* into the #GHashTable. It is also not advisable to mix static strings
|
|
||||||
* and dynamically-allocated strings in a #GHashTable, because it then
|
|
||||||
* becomes difficult to determine whether the string should be freed.
|
|
||||||
*
|
|
||||||
* To create a #GHashTable, use g_hash_table_new().
|
|
||||||
*
|
|
||||||
* To insert a key and value into a #GHashTable, use
|
|
||||||
* g_hash_table_insert().
|
|
||||||
*
|
|
||||||
* To look up a value corresponding to a given key, use
|
|
||||||
* g_hash_table_lookup() and g_hash_table_lookup_extended().
|
|
||||||
*
|
|
||||||
* g_hash_table_lookup_extended() can also be used to simply
|
|
||||||
* check if a key is present in the hash table.
|
|
||||||
*
|
|
||||||
* To remove a key and value, use g_hash_table_remove().
|
|
||||||
*
|
|
||||||
* To call a function for each key and value pair use
|
|
||||||
* g_hash_table_foreach() or use an iterator to iterate over the
|
|
||||||
* key/value pairs in the hash table, see #GHashTableIter. The iteration order
|
|
||||||
* of a hash table is not defined, and you must not rely on iterating over
|
|
||||||
* keys/values in the same order as they were inserted.
|
|
||||||
*
|
|
||||||
* To destroy a #GHashTable use g_hash_table_destroy().
|
|
||||||
*
|
|
||||||
* A common use-case for hash tables is to store information about a
|
|
||||||
* set of keys, without associating any particular value with each
|
|
||||||
* key. GHashTable optimizes one way of doing so: If you store only
|
|
||||||
* key-value pairs where key == value, then GHashTable does not
|
|
||||||
* allocate memory to store the values, which can be a considerable
|
|
||||||
* space saving, if your set is large. The functions
|
|
||||||
* g_hash_table_add() and g_hash_table_contains() are designed to be
|
|
||||||
* used when using #GHashTable this way.
|
|
||||||
*
|
|
||||||
* #GHashTable is not designed to be statically initialised with keys and
|
|
||||||
* values known at compile time. To build a static hash table, use a tool such
|
|
||||||
* as [gperf](https://www.gnu.org/software/gperf/).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GHashTable:
|
* GHashTable:
|
||||||
*
|
*
|
||||||
|
@ -74,23 +74,22 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gkeyfile
|
* GKeyFile:
|
||||||
* @title: Key-value file parser
|
|
||||||
* @short_description: parses .ini-like config files
|
|
||||||
*
|
*
|
||||||
* #GKeyFile lets you parse, edit or create files containing groups of
|
* `GKeyFile` parses .ini-like config files.
|
||||||
|
*
|
||||||
|
* `GKeyFile` lets you parse, edit or create files containing groups of
|
||||||
* key-value pairs, which we call "key files" for lack of a better name.
|
* key-value pairs, which we call "key files" for lack of a better name.
|
||||||
* Several freedesktop.org specifications use key files now, e.g the
|
* Several freedesktop.org specifications use key files now, e.g the
|
||||||
* [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec)
|
* [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec)
|
||||||
* and the
|
* and the [Icon Theme Specification](http://freedesktop.org/Standards/icon-theme-spec).
|
||||||
* [Icon Theme Specification](http://freedesktop.org/Standards/icon-theme-spec).
|
|
||||||
*
|
*
|
||||||
* The syntax of key files is described in detail in the
|
* The syntax of key files is described in detail in the
|
||||||
* [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec),
|
* [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec),
|
||||||
* here is a quick summary: Key files
|
* here is a quick summary: Key files consists of groups of key-value pairs, interspersed
|
||||||
* consists of groups of key-value pairs, interspersed with comments.
|
* with comments.
|
||||||
*
|
*
|
||||||
* |[
|
* ```txt
|
||||||
* # this is just an example
|
* # this is just an example
|
||||||
* # there can be comments before the first group
|
* # there can be comments before the first group
|
||||||
*
|
*
|
||||||
@ -110,7 +109,7 @@
|
|||||||
* Numbers=2;20;-200;0
|
* Numbers=2;20;-200;0
|
||||||
*
|
*
|
||||||
* Booleans=true;false;true;true
|
* Booleans=true;false;true;true
|
||||||
* ]|
|
* ```
|
||||||
*
|
*
|
||||||
* Lines beginning with a '#' and blank lines are considered comments.
|
* Lines beginning with a '#' and blank lines are considered comments.
|
||||||
*
|
*
|
||||||
@ -118,15 +117,13 @@
|
|||||||
* in '[' and ']', and ended implicitly by the start of the next group or
|
* in '[' and ']', and ended implicitly by the start of the next group or
|
||||||
* the end of the file. Each key-value pair must be contained in a group.
|
* the end of the file. Each key-value pair must be contained in a group.
|
||||||
*
|
*
|
||||||
* Key-value pairs generally have the form `key=value`, with the
|
* Key-value pairs generally have the form `key=value`, with the exception
|
||||||
* exception of localized strings, which have the form
|
* of localized strings, which have the form `key[locale]=value`, with a
|
||||||
* `key[locale]=value`, with a locale identifier of the
|
* locale identifier of the form `lang_COUNTRY@MODIFIER` where `COUNTRY`
|
||||||
* form `lang_COUNTRY@MODIFIER` where `COUNTRY` and `MODIFIER`
|
* and `MODIFIER` are optional. Space before and after the '=' character
|
||||||
* are optional.
|
* are ignored. Newline, tab, carriage return and backslash characters in
|
||||||
* Space before and after the '=' character are ignored. Newline, tab,
|
* value are escaped as `\n`, `\t`, `\r`, and `\\\\`, respectively. To preserve
|
||||||
* carriage return and backslash characters in value are escaped as \n,
|
* leading spaces in values, these can also be escaped as `\s`.
|
||||||
* \t, \r, and \\\\, respectively. To preserve leading spaces in values,
|
|
||||||
* these can also be escaped as \s.
|
|
||||||
*
|
*
|
||||||
* Key files can store strings (possibly with localized variants), integers,
|
* Key files can store strings (possibly with localized variants), integers,
|
||||||
* booleans and lists of these. Lists are separated by a separator character,
|
* booleans and lists of these. Lists are separated by a separator character,
|
||||||
@ -153,15 +150,14 @@
|
|||||||
*
|
*
|
||||||
* Note that in contrast to the
|
* Note that in contrast to the
|
||||||
* [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec),
|
* [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec),
|
||||||
* groups in key files may contain the same
|
* groups in key files may contain the same key multiple times; the last entry wins.
|
||||||
* key multiple times; the last entry wins. Key files may also contain
|
* Key files may also contain multiple groups with the same name; they are merged
|
||||||
* multiple groups with the same name; they are merged together.
|
* together. Another difference is that keys and group names in key files are not
|
||||||
* Another difference is that keys and group names in key files are not
|
|
||||||
* restricted to ASCII characters.
|
* restricted to ASCII characters.
|
||||||
*
|
*
|
||||||
* Here is an example of loading a key file and reading a value:
|
* Here is an example of loading a key file and reading a value:
|
||||||
*
|
*
|
||||||
* |[<!-- language="C" -->
|
* ```c
|
||||||
* g_autoptr(GError) error = NULL;
|
* g_autoptr(GError) error = NULL;
|
||||||
* g_autoptr(GKeyFile) key_file = g_key_file_new ();
|
* g_autoptr(GKeyFile) key_file = g_key_file_new ();
|
||||||
*
|
*
|
||||||
@ -184,11 +180,11 @@
|
|||||||
* // Fall back to a default value.
|
* // Fall back to a default value.
|
||||||
* val = g_strdup ("default-value");
|
* val = g_strdup ("default-value");
|
||||||
* }
|
* }
|
||||||
* ]|
|
* ```
|
||||||
*
|
*
|
||||||
* Here is an example of creating and saving a key file:
|
* Here is an example of creating and saving a key file:
|
||||||
*
|
*
|
||||||
* |[<!-- language="C" -->
|
* ```c
|
||||||
* g_autoptr(GKeyFile) key_file = g_key_file_new ();
|
* g_autoptr(GKeyFile) key_file = g_key_file_new ();
|
||||||
* const gchar *val = …;
|
* const gchar *val = …;
|
||||||
* g_autoptr(GError) error = NULL;
|
* g_autoptr(GError) error = NULL;
|
||||||
@ -211,7 +207,7 @@
|
|||||||
* return;
|
* return;
|
||||||
* }
|
* }
|
||||||
* g_autoptr(GBytes) bytes = g_bytes_new_take (g_steal_pointer (&data), data_len);
|
* g_autoptr(GBytes) bytes = g_bytes_new_take (g_steal_pointer (&data), data_len);
|
||||||
* ]|
|
* ```
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -499,12 +495,6 @@
|
|||||||
|
|
||||||
typedef struct _GKeyFileGroup GKeyFileGroup;
|
typedef struct _GKeyFileGroup GKeyFileGroup;
|
||||||
|
|
||||||
/**
|
|
||||||
* GKeyFile:
|
|
||||||
*
|
|
||||||
* The GKeyFile struct contains only private data
|
|
||||||
* and should not be accessed directly.
|
|
||||||
*/
|
|
||||||
struct _GKeyFile
|
struct _GKeyFile
|
||||||
{
|
{
|
||||||
GList *groups;
|
GList *groups;
|
||||||
|
84
glib/glist.c
84
glib/glist.c
@ -36,90 +36,6 @@
|
|||||||
|
|
||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:linked_lists_double
|
|
||||||
* @title: Doubly-Linked Lists
|
|
||||||
* @short_description: linked lists that can be iterated over in both directions
|
|
||||||
*
|
|
||||||
* The #GList structure and its associated functions provide a standard
|
|
||||||
* doubly-linked list data structure. The benefit of this data-structure
|
|
||||||
* is to provide insertion/deletion operations in O(1) complexity where
|
|
||||||
* access/search operations are in O(n). The benefit of #GList over
|
|
||||||
* #GSList (singly linked list) is that the worst case on access/search
|
|
||||||
* operations is divided by two which comes at a cost in space as we need
|
|
||||||
* to retain two pointers in place of one.
|
|
||||||
*
|
|
||||||
* Each element in the list contains a piece of data, together with
|
|
||||||
* pointers which link to the previous and next elements in the list.
|
|
||||||
* Using these pointers it is possible to move through the list in both
|
|
||||||
* directions (unlike the singly-linked [GSList][glib-Singly-Linked-Lists],
|
|
||||||
* which only allows movement through the list in the forward direction).
|
|
||||||
*
|
|
||||||
* The double linked list does not keep track of the number of items
|
|
||||||
* and does not keep track of both the start and end of the list. If
|
|
||||||
* you want fast access to both the start and the end of the list,
|
|
||||||
* and/or the number of items in the list, use a
|
|
||||||
* [GQueue][glib-Double-ended-Queues] instead.
|
|
||||||
*
|
|
||||||
* The data contained in each element can be either integer values, by
|
|
||||||
* using one of the [Type Conversion Macros][glib-Type-Conversion-Macros],
|
|
||||||
* or simply pointers to any type of data.
|
|
||||||
*
|
|
||||||
* List elements are allocated from the [slice allocator][glib-Memory-Slices],
|
|
||||||
* which is more efficient than allocating elements individually.
|
|
||||||
*
|
|
||||||
* Note that most of the #GList functions expect to be passed a pointer
|
|
||||||
* to the first element in the list. The functions which insert
|
|
||||||
* elements return the new start of the list, which may have changed.
|
|
||||||
*
|
|
||||||
* There is no function to create a #GList. %NULL is considered to be
|
|
||||||
* a valid, empty list so you simply set a #GList* to %NULL to initialize
|
|
||||||
* it.
|
|
||||||
*
|
|
||||||
* To add elements, use g_list_append(), g_list_prepend(),
|
|
||||||
* g_list_insert() and g_list_insert_sorted().
|
|
||||||
*
|
|
||||||
* To visit all elements in the list, use a loop over the list:
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* GList *l;
|
|
||||||
* for (l = list; l != NULL; l = l->next)
|
|
||||||
* {
|
|
||||||
* // do something with l->data
|
|
||||||
* }
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* To call a function for each element in the list, use g_list_foreach().
|
|
||||||
*
|
|
||||||
* To loop over the list and modify it (e.g. remove a certain element)
|
|
||||||
* a while loop is more appropriate, for example:
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* GList *l = list;
|
|
||||||
* while (l != NULL)
|
|
||||||
* {
|
|
||||||
* GList *next = l->next;
|
|
||||||
* if (should_be_removed (l))
|
|
||||||
* {
|
|
||||||
* // possibly free l->data
|
|
||||||
* list = g_list_delete_link (list, l);
|
|
||||||
* }
|
|
||||||
* l = next;
|
|
||||||
* }
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* To remove elements, use g_list_remove().
|
|
||||||
*
|
|
||||||
* To navigate in a list, use g_list_first(), g_list_last(),
|
|
||||||
* g_list_next(), g_list_previous().
|
|
||||||
*
|
|
||||||
* To find elements in the list use g_list_nth(), g_list_nth_data(),
|
|
||||||
* g_list_find() and g_list_find_custom().
|
|
||||||
*
|
|
||||||
* To find the index of an element use g_list_position() and
|
|
||||||
* g_list_index().
|
|
||||||
*
|
|
||||||
* To free the entire list, use g_list_free() or g_list_free_full().
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GList:
|
* GList:
|
||||||
* @data: holds the element's data, which can be a pointer to any kind
|
* @data: holds the element's data, which can be a pointer to any kind
|
||||||
|
37
glib/gnode.c
37
glib/gnode.c
@ -39,43 +39,6 @@
|
|||||||
|
|
||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:trees-nary
|
|
||||||
* @title: N-ary Trees
|
|
||||||
* @short_description: trees of data with any number of branches
|
|
||||||
*
|
|
||||||
* The #GNode struct and its associated functions provide a N-ary tree
|
|
||||||
* data structure, where nodes in the tree can contain arbitrary data.
|
|
||||||
*
|
|
||||||
* To create a new tree use g_node_new().
|
|
||||||
*
|
|
||||||
* To insert a node into a tree use g_node_insert(),
|
|
||||||
* g_node_insert_before(), g_node_append() and g_node_prepend().
|
|
||||||
*
|
|
||||||
* To create a new node and insert it into a tree use
|
|
||||||
* g_node_insert_data(), g_node_insert_data_after(),
|
|
||||||
* g_node_insert_data_before(), g_node_append_data()
|
|
||||||
* and g_node_prepend_data().
|
|
||||||
*
|
|
||||||
* To reverse the children of a node use g_node_reverse_children().
|
|
||||||
*
|
|
||||||
* To find a node use g_node_get_root(), g_node_find(),
|
|
||||||
* g_node_find_child(), g_node_child_index(), g_node_child_position(),
|
|
||||||
* g_node_first_child(), g_node_last_child(), g_node_nth_child(),
|
|
||||||
* g_node_first_sibling(), g_node_prev_sibling(), g_node_next_sibling()
|
|
||||||
* or g_node_last_sibling().
|
|
||||||
*
|
|
||||||
* To get information about a node or tree use G_NODE_IS_LEAF(),
|
|
||||||
* G_NODE_IS_ROOT(), g_node_depth(), g_node_n_nodes(),
|
|
||||||
* g_node_n_children(), g_node_is_ancestor() or g_node_max_height().
|
|
||||||
*
|
|
||||||
* To traverse a tree, calling a function for each node visited in the
|
|
||||||
* traversal, use g_node_traverse() or g_node_children_foreach().
|
|
||||||
*
|
|
||||||
* To remove a node or subtree from a tree use g_node_unlink() or
|
|
||||||
* g_node_destroy().
|
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GNode:
|
* GNode:
|
||||||
* @data: contains the actual data of the node.
|
* @data: contains the actual data of the node.
|
||||||
|
@ -15,15 +15,13 @@
|
|||||||
#include "gstrfuncs.h"
|
#include "gstrfuncs.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gpathbuf
|
* GPathBuf:
|
||||||
* @Title: GPathBuf
|
|
||||||
* @Short_description: A mutable path builder
|
|
||||||
*
|
*
|
||||||
* `GPathBuf` is a helper type that allows you to easily build paths from
|
* `GPathBuf` is a helper type that allows you to easily build paths from
|
||||||
* individual elements, using the platform specific conventions for path
|
* individual elements, using the platform specific conventions for path
|
||||||
* separators.
|
* separators.
|
||||||
*
|
*
|
||||||
* |[<!-- language="C" -->
|
* ```c
|
||||||
* g_auto (GPathBuf) path;
|
* g_auto (GPathBuf) path;
|
||||||
*
|
*
|
||||||
* g_path_buf_init (&path);
|
* g_path_buf_init (&path);
|
||||||
@ -34,11 +32,11 @@
|
|||||||
*
|
*
|
||||||
* g_autofree char *echo = g_path_buf_to_path (&path);
|
* g_autofree char *echo = g_path_buf_to_path (&path);
|
||||||
* g_assert_cmpstr (echo, ==, "/usr/bin/echo");
|
* g_assert_cmpstr (echo, ==, "/usr/bin/echo");
|
||||||
* ]|
|
* ```
|
||||||
*
|
*
|
||||||
* You can also load a full path and then operate on its components:
|
* You can also load a full path and then operate on its components:
|
||||||
*
|
*
|
||||||
* |[<!-- language="C" -->
|
* ```c
|
||||||
* g_auto (GPathBuf) path;
|
* g_auto (GPathBuf) path;
|
||||||
*
|
*
|
||||||
* g_path_buf_init_from_path (&path, "/usr/bin/echo");
|
* g_path_buf_init_from_path (&path, "/usr/bin/echo");
|
||||||
@ -48,9 +46,9 @@
|
|||||||
*
|
*
|
||||||
* g_autofree char *sh = g_path_buf_to_path (&path);
|
* g_autofree char *sh = g_path_buf_to_path (&path);
|
||||||
* g_assert_cmpstr (sh, ==, "/usr/bin/sh");
|
* g_assert_cmpstr (sh, ==, "/usr/bin/sh");
|
||||||
* ]|
|
* ```
|
||||||
*
|
*
|
||||||
* `GPathBuf` is available since GLib 2.76.
|
* Since: 2.76
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -16,13 +16,6 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
typedef struct _GPathBuf GPathBuf;
|
typedef struct _GPathBuf GPathBuf;
|
||||||
|
|
||||||
/**
|
|
||||||
* GPathBuf: (copy-func g_path_buf_copy) (free-func g_path_buf_free)
|
|
||||||
*
|
|
||||||
* A mutable path builder.
|
|
||||||
*
|
|
||||||
* Since: 2.76
|
|
||||||
*/
|
|
||||||
struct _GPathBuf
|
struct _GPathBuf
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
@ -31,32 +31,24 @@
|
|||||||
#include "gutils.h"
|
#include "gutils.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:patterns
|
* GPatternSpec:
|
||||||
* @title: Glob-style pattern matching
|
|
||||||
* @short_description: matches strings against patterns containing '*'
|
|
||||||
* (wildcard) and '?' (joker)
|
|
||||||
*
|
*
|
||||||
* The g_pattern_match* functions match a string
|
* A `GPatternSpec` struct is the 'compiled' form of a glob-style pattern.
|
||||||
* against a pattern containing '*' and '?' wildcards with similar
|
*
|
||||||
* semantics as the standard glob() function: '*' matches an arbitrary,
|
* The [func@g_pattern_match_simple] and [method@GLib.PatternSpec.match] functions
|
||||||
|
* match a string against a pattern containing '*' and '?' wildcards with similar
|
||||||
|
* semantics as the standard `glob()` function: '*' matches an arbitrary,
|
||||||
* possibly empty, string, '?' matches an arbitrary character.
|
* possibly empty, string, '?' matches an arbitrary character.
|
||||||
*
|
*
|
||||||
* Note that in contrast to glob(), the '/' character can be matched by
|
* Note that in contrast to `glob()`, the '/' character can be matched by
|
||||||
* the wildcards, there are no '[...]' character ranges and '*' and '?'
|
* the wildcards, there are no '[...]' character ranges and '*' and '?'
|
||||||
* can not be escaped to include them literally in a pattern.
|
* can not be escaped to include them literally in a pattern.
|
||||||
*
|
*
|
||||||
* When multiple strings must be matched against the same pattern, it
|
* When multiple strings must be matched against the same pattern, it is better
|
||||||
* is better to compile the pattern to a #GPatternSpec using
|
* to compile the pattern to a [struct@GLib.PatternSpec] using
|
||||||
* g_pattern_spec_new() and use g_pattern_match_string() instead of
|
* [method@GLib.PatternSpec.new] and use [method@GLib.PatternSpec.match_string]
|
||||||
* g_pattern_match_simple(). This avoids the overhead of repeated
|
* instead of [func@g_pattern_match_simple]. This avoids the overhead of repeated
|
||||||
* pattern compilation.
|
* pattern compilation.
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GPatternSpec:
|
|
||||||
*
|
|
||||||
* A GPatternSpec struct is the 'compiled' form of a pattern. This
|
|
||||||
* structure is opaque and its fields cannot be accessed directly.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* keep enum and structure of gpattern.c and patterntest.c in sync */
|
/* keep enum and structure of gpattern.c and patterntest.c in sync */
|
||||||
|
@ -67,40 +67,34 @@ g_quark_init (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:quarks
|
* GQuark:
|
||||||
* @title: Quarks
|
|
||||||
* @short_description: a 2-way association between a string and a
|
|
||||||
* unique integer identifier
|
|
||||||
*
|
*
|
||||||
* Quarks are associations between strings and integer identifiers.
|
* A GQuark is a non-zero integer which uniquely identifies a
|
||||||
* Given either the string or the #GQuark identifier it is possible to
|
* particular string.
|
||||||
|
*
|
||||||
|
* A GQuark value of zero is associated to `NULL`.
|
||||||
|
*
|
||||||
|
* Given either the string or the `GQuark` identifier it is possible to
|
||||||
* retrieve the other.
|
* retrieve the other.
|
||||||
*
|
*
|
||||||
* Quarks are used for both [datasets][glib-Datasets] and
|
* Quarks are used for both [datasets][glib-Datasets] and
|
||||||
* [keyed data lists][glib-Keyed-Data-Lists].
|
* [keyed data lists][glib-Keyed-Data-Lists].
|
||||||
*
|
*
|
||||||
* To create a new quark from a string, use g_quark_from_string() or
|
* To create a new quark from a string, use [func@GLib.quark_from_string]
|
||||||
* g_quark_from_static_string().
|
* or [func@GLib.quark_from_static_string].
|
||||||
*
|
*
|
||||||
* To find the string corresponding to a given #GQuark, use
|
* To find the string corresponding to a given `GQuark`, use
|
||||||
* g_quark_to_string().
|
* [func@GLib.quark_to_string].
|
||||||
*
|
*
|
||||||
* To find the #GQuark corresponding to a given string, use
|
* To find the `GQuark` corresponding to a given string, use
|
||||||
* g_quark_try_string().
|
* [func@GLib.quark_try_string].
|
||||||
*
|
*
|
||||||
* Another use for the string pool maintained for the quark functions
|
* Another use for the string pool maintained for the quark functions
|
||||||
* is string interning, using g_intern_string() or
|
* is string interning, using [func@GLib.intern_string] or
|
||||||
* g_intern_static_string(). An interned string is a canonical
|
* [func@GLib.intern_static_string]. An interned string is a canonical
|
||||||
* representation for a string. One important advantage of interned
|
* representation for a string. One important advantage of interned
|
||||||
* strings is that they can be compared for equality by a simple
|
* strings is that they can be compared for equality by a simple
|
||||||
* pointer comparison, rather than using strcmp().
|
* pointer comparison, rather than using `strcmp()`.
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GQuark:
|
|
||||||
*
|
|
||||||
* A GQuark is a non-zero integer which uniquely identifies a
|
|
||||||
* particular string. A GQuark value of zero is associated to %NULL.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,35 +24,6 @@
|
|||||||
* MT safe
|
* MT safe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:queue
|
|
||||||
* @Title: Double-ended Queues
|
|
||||||
* @Short_description: double-ended queue data structure
|
|
||||||
*
|
|
||||||
* The #GQueue structure and its associated functions provide a standard
|
|
||||||
* queue data structure. Internally, GQueue uses the same data structure
|
|
||||||
* as #GList to store elements with the same complexity over
|
|
||||||
* insertion/deletion (O(1)) and access/search (O(n)) operations.
|
|
||||||
*
|
|
||||||
* The data contained in each element can be either integer values, by
|
|
||||||
* using one of the [Type Conversion Macros][glib-Type-Conversion-Macros],
|
|
||||||
* or simply pointers to any type of data.
|
|
||||||
*
|
|
||||||
* As with all other GLib data structures, #GQueue is not thread-safe.
|
|
||||||
* For a thread-safe queue, use #GAsyncQueue.
|
|
||||||
*
|
|
||||||
* To create a new GQueue, use g_queue_new().
|
|
||||||
*
|
|
||||||
* To initialize a statically-allocated GQueue, use %G_QUEUE_INIT or
|
|
||||||
* g_queue_init().
|
|
||||||
*
|
|
||||||
* To add elements, use g_queue_push_head(), g_queue_push_head_link(),
|
|
||||||
* g_queue_push_tail() and g_queue_push_tail_link().
|
|
||||||
*
|
|
||||||
* To remove elements, use g_queue_pop_head() and g_queue_pop_tail().
|
|
||||||
*
|
|
||||||
* To free the entire queue, use g_queue_free().
|
|
||||||
*/
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "gqueue.h"
|
#include "gqueue.h"
|
||||||
|
@ -18,74 +18,6 @@
|
|||||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:refstring
|
|
||||||
* @Title: Reference counted strings
|
|
||||||
* @Short_description: Strings with reference counted memory management
|
|
||||||
*
|
|
||||||
* Reference counted strings are normal C strings that have been augmented
|
|
||||||
* with a reference counter to manage their resources. You allocate a new
|
|
||||||
* reference counted string and acquire and release references as needed,
|
|
||||||
* instead of copying the string among callers; when the last reference on
|
|
||||||
* the string is released, the resources allocated for it are freed.
|
|
||||||
*
|
|
||||||
* Typically, reference counted strings can be used when parsing data from
|
|
||||||
* files and storing them into data structures that are passed to various
|
|
||||||
* callers:
|
|
||||||
*
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* PersonDetails *
|
|
||||||
* person_details_from_data (const char *data)
|
|
||||||
* {
|
|
||||||
* // Use g_autoptr() to simplify error cases
|
|
||||||
* g_autoptr(GRefString) full_name = NULL;
|
|
||||||
* g_autoptr(GRefString) address = NULL;
|
|
||||||
* g_autoptr(GRefString) city = NULL;
|
|
||||||
* g_autoptr(GRefString) state = NULL;
|
|
||||||
* g_autoptr(GRefString) zip_code = NULL;
|
|
||||||
*
|
|
||||||
* // parse_person_details() is defined elsewhere; returns refcounted strings
|
|
||||||
* if (!parse_person_details (data, &full_name, &address, &city, &state, &zip_code))
|
|
||||||
* return NULL;
|
|
||||||
*
|
|
||||||
* if (!validate_zip_code (zip_code))
|
|
||||||
* return NULL;
|
|
||||||
*
|
|
||||||
* // add_address_to_cache() and add_full_name_to_cache() are defined
|
|
||||||
* // elsewhere; they add strings to various caches, using refcounted
|
|
||||||
* // strings to avoid copying data over and over again
|
|
||||||
* add_address_to_cache (address, city, state, zip_code);
|
|
||||||
* add_full_name_to_cache (full_name);
|
|
||||||
*
|
|
||||||
* // person_details_new() is defined elsewhere; it takes a reference
|
|
||||||
* // on each string
|
|
||||||
* PersonDetails *res = person_details_new (full_name,
|
|
||||||
* address,
|
|
||||||
* city,
|
|
||||||
* state,
|
|
||||||
* zip_code);
|
|
||||||
*
|
|
||||||
* return res;
|
|
||||||
* }
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* In the example above, we have multiple functions taking the same strings
|
|
||||||
* for different uses; with typical C strings, we'd have to copy the strings
|
|
||||||
* every time the life time rules of the data differ from the life time of
|
|
||||||
* the string parsed from the original buffer. With reference counted strings,
|
|
||||||
* each caller can take a reference on the data, and keep it as long as it
|
|
||||||
* needs to own the string.
|
|
||||||
*
|
|
||||||
* Reference counted strings can also be "interned" inside a global table
|
|
||||||
* owned by GLib; while an interned string has at least a reference, creating
|
|
||||||
* a new interned reference counted string with the same contents will return
|
|
||||||
* a reference to the existing string instead of creating a new reference
|
|
||||||
* counted string instance. Once the string loses its last reference, it will
|
|
||||||
* be automatically removed from the global interned strings table.
|
|
||||||
*
|
|
||||||
* Since: 2.58
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "grefstring.h"
|
#include "grefstring.h"
|
||||||
|
@ -40,14 +40,12 @@
|
|||||||
#include "gthread.h"
|
#include "gthread.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gregex
|
* GRegex:
|
||||||
* @title: Perl-compatible regular expressions
|
|
||||||
* @short_description: matches strings against regular expressions
|
|
||||||
* @see_also: [Regular expression syntax][glib-regex-syntax]
|
|
||||||
*
|
*
|
||||||
* The g_regex_*() functions implement regular
|
* A `GRegex` is the "compiled" form of a regular expression pattern.
|
||||||
* expression pattern matching using syntax and semantics similar to
|
*
|
||||||
* Perl regular expression.
|
* `GRegex` implements regular expression pattern matching using syntax and
|
||||||
|
* semantics similar to Perl regular expression.
|
||||||
*
|
*
|
||||||
* Some functions accept a @start_position argument, setting it differs
|
* Some functions accept a @start_position argument, setting it differs
|
||||||
* from just passing over a shortened string and setting %G_REGEX_MATCH_NOTBOL
|
* from just passing over a shortened string and setting %G_REGEX_MATCH_NOTBOL
|
||||||
@ -81,23 +79,23 @@
|
|||||||
* The behaviour of the dot, circumflex, and dollar metacharacters are
|
* The behaviour of the dot, circumflex, and dollar metacharacters are
|
||||||
* affected by newline characters, the default is to recognize any newline
|
* affected by newline characters, the default is to recognize any newline
|
||||||
* character (the same characters recognized by "\R"). This can be changed
|
* character (the same characters recognized by "\R"). This can be changed
|
||||||
* with %G_REGEX_NEWLINE_CR, %G_REGEX_NEWLINE_LF and %G_REGEX_NEWLINE_CRLF
|
* with `G_REGEX_NEWLINE_CR`, `G_REGEX_NEWLINE_LF` and `G_REGEX_NEWLINE_CRLF`
|
||||||
* compile options, and with %G_REGEX_MATCH_NEWLINE_ANY,
|
* compile options, and with `G_REGEX_MATCH_NEWLINE_ANY`,
|
||||||
* %G_REGEX_MATCH_NEWLINE_CR, %G_REGEX_MATCH_NEWLINE_LF and
|
* `G_REGEX_MATCH_NEWLINE_CR`, `G_REGEX_MATCH_NEWLINE_LF` and
|
||||||
* %G_REGEX_MATCH_NEWLINE_CRLF match options. These settings are also
|
* `G_REGEX_MATCH_NEWLINE_CRLF` match options. These settings are also
|
||||||
* relevant when compiling a pattern if %G_REGEX_EXTENDED is set, and an
|
* relevant when compiling a pattern if `G_REGEX_EXTENDED` is set, and an
|
||||||
* unescaped "#" outside a character class is encountered. This indicates
|
* unescaped "#" outside a character class is encountered. This indicates
|
||||||
* a comment that lasts until after the next newline.
|
* a comment that lasts until after the next newline.
|
||||||
*
|
*
|
||||||
* Creating and manipulating the same #GRegex structure from different
|
* Creating and manipulating the same `GRegex` structure from different
|
||||||
* threads is not a problem as #GRegex does not modify its internal
|
* threads is not a problem as `GRegex` does not modify its internal
|
||||||
* state between creation and destruction, on the other hand #GMatchInfo
|
* state between creation and destruction, on the other hand `GMatchInfo`
|
||||||
* is not threadsafe.
|
* is not threadsafe.
|
||||||
*
|
*
|
||||||
* The regular expressions low-level functionalities are obtained through
|
* The regular expressions low-level functionalities are obtained through
|
||||||
* the excellent
|
* the excellent [PCRE](http://www.pcre.org/) library written by Philip Hazel.
|
||||||
* [PCRE](http://www.pcre.org/)
|
*
|
||||||
* library written by Philip Hazel.
|
* Since: 2.14
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define G_REGEX_PCRE_GENERIC_MASK (PCRE2_ANCHORED | \
|
#define G_REGEX_PCRE_GENERIC_MASK (PCRE2_ANCHORED | \
|
||||||
|
@ -413,14 +413,6 @@ typedef enum
|
|||||||
G_REGEX_MATCH_NOTEMPTY_ATSTART = 1 << 28
|
G_REGEX_MATCH_NOTEMPTY_ATSTART = 1 << 28
|
||||||
} GRegexMatchFlags;
|
} GRegexMatchFlags;
|
||||||
|
|
||||||
/**
|
|
||||||
* GRegex:
|
|
||||||
*
|
|
||||||
* A GRegex is the "compiled" form of a regular expression pattern.
|
|
||||||
* This structure is opaque and its fields cannot be accessed directly.
|
|
||||||
*
|
|
||||||
* Since: 2.14
|
|
||||||
*/
|
|
||||||
typedef struct _GRegex GRegex;
|
typedef struct _GRegex GRegex;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,15 +54,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:scanner
|
|
||||||
* @title: Lexical Scanner
|
|
||||||
* @short_description: a general purpose lexical scanner
|
|
||||||
*
|
|
||||||
* The #GScanner and its associated functions provide a
|
|
||||||
* general purpose lexical scanner.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GScannerMsgFunc:
|
* GScannerMsgFunc:
|
||||||
* @scanner: a #GScanner
|
* @scanner: a #GScanner
|
||||||
@ -196,7 +187,7 @@
|
|||||||
* @next_position: char number of the last token from g_scanner_peek_next_token()
|
* @next_position: char number of the last token from g_scanner_peek_next_token()
|
||||||
* @msg_handler: handler function for _warn and _error
|
* @msg_handler: handler function for _warn and _error
|
||||||
*
|
*
|
||||||
* The data structure representing a lexical scanner.
|
* `GScanner` provides a general-purpose lexical scanner.
|
||||||
*
|
*
|
||||||
* You should set @input_name after creating the scanner, since
|
* You should set @input_name after creating the scanner, since
|
||||||
* it is used by the default message handler when displaying
|
* it is used by the default message handler when displaying
|
||||||
|
@ -25,54 +25,6 @@
|
|||||||
#include "gmem.h"
|
#include "gmem.h"
|
||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
#include "gslice.h"
|
#include "gslice.h"
|
||||||
/**
|
|
||||||
* SECTION:sequence
|
|
||||||
* @title: Sequences
|
|
||||||
* @short_description: scalable lists
|
|
||||||
*
|
|
||||||
* The #GSequence data structure has the API of a list, but is
|
|
||||||
* implemented internally with a balanced binary tree. This means that
|
|
||||||
* most of the operations (access, search, insertion, deletion, ...) on
|
|
||||||
* #GSequence are O(log(n)) in average and O(n) in worst case for time
|
|
||||||
* complexity. But, note that maintaining a balanced sorted list of n
|
|
||||||
* elements is done in time O(n log(n)).
|
|
||||||
* The data contained in each element can be either integer values, by using
|
|
||||||
* of the [Type Conversion Macros][glib-Type-Conversion-Macros], or simply
|
|
||||||
* pointers to any type of data.
|
|
||||||
*
|
|
||||||
* A #GSequence is accessed through "iterators", represented by a
|
|
||||||
* #GSequenceIter. An iterator represents a position between two
|
|
||||||
* elements of the sequence. For example, the "begin" iterator
|
|
||||||
* represents the gap immediately before the first element of the
|
|
||||||
* sequence, and the "end" iterator represents the gap immediately
|
|
||||||
* after the last element. In an empty sequence, the begin and end
|
|
||||||
* iterators are the same.
|
|
||||||
*
|
|
||||||
* Some methods on #GSequence operate on ranges of items. For example
|
|
||||||
* g_sequence_foreach_range() will call a user-specified function on
|
|
||||||
* each element with the given range. The range is delimited by the
|
|
||||||
* gaps represented by the passed-in iterators, so if you pass in the
|
|
||||||
* begin and end iterators, the range in question is the entire
|
|
||||||
* sequence.
|
|
||||||
*
|
|
||||||
* The function g_sequence_get() is used with an iterator to access the
|
|
||||||
* element immediately following the gap that the iterator represents.
|
|
||||||
* The iterator is said to "point" to that element.
|
|
||||||
*
|
|
||||||
* Iterators are stable across most operations on a #GSequence. For
|
|
||||||
* example an iterator pointing to some element of a sequence will
|
|
||||||
* continue to point to that element even after the sequence is sorted.
|
|
||||||
* Even moving an element to another sequence using for example
|
|
||||||
* g_sequence_move_range() will not invalidate the iterators pointing
|
|
||||||
* to it. The only operation that will invalidate an iterator is when
|
|
||||||
* the element it points to is removed from any sequence.
|
|
||||||
*
|
|
||||||
* To sort the data, either use g_sequence_insert_sorted() or
|
|
||||||
* g_sequence_insert_sorted_iter() to add data to the #GSequence or, if
|
|
||||||
* you want to add a large amount of data, it is more efficient to call
|
|
||||||
* g_sequence_sort() or g_sequence_sort_iter() after doing unsorted
|
|
||||||
* insertions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GSequenceIter:
|
* GSequenceIter:
|
||||||
|
@ -35,57 +35,6 @@
|
|||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
#include "gslice.h"
|
#include "gslice.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:linked_lists_single
|
|
||||||
* @title: Singly-Linked Lists
|
|
||||||
* @short_description: linked lists that can be iterated in one direction
|
|
||||||
*
|
|
||||||
* The #GSList structure and its associated functions provide a
|
|
||||||
* standard singly-linked list data structure. The benefit of this
|
|
||||||
* data-structure is to provide insertion/deletion operations in O(1)
|
|
||||||
* complexity where access/search operations are in O(n). The benefit
|
|
||||||
* of #GSList over #GList (doubly linked list) is that they are lighter
|
|
||||||
* in space as they only need to retain one pointer but it double the
|
|
||||||
* cost of the worst case access/search operations.
|
|
||||||
*
|
|
||||||
* Each element in the list contains a piece of data, together with a
|
|
||||||
* pointer which links to the next element in the list. Using this
|
|
||||||
* pointer it is possible to move through the list in one direction
|
|
||||||
* only (unlike the [double-linked lists][glib-Doubly-Linked-Lists],
|
|
||||||
* which allow movement in both directions).
|
|
||||||
*
|
|
||||||
* The data contained in each element can be either integer values, by
|
|
||||||
* using one of the [Type Conversion Macros][glib-Type-Conversion-Macros],
|
|
||||||
* or simply pointers to any type of data.
|
|
||||||
*
|
|
||||||
* List elements are allocated from the [slice allocator][glib-Memory-Slices],
|
|
||||||
* which is more efficient than allocating elements individually.
|
|
||||||
*
|
|
||||||
* Note that most of the #GSList functions expect to be passed a
|
|
||||||
* pointer to the first element in the list. The functions which insert
|
|
||||||
* elements return the new start of the list, which may have changed.
|
|
||||||
*
|
|
||||||
* There is no function to create a #GSList. %NULL is considered to be
|
|
||||||
* the empty list so you simply set a #GSList* to %NULL.
|
|
||||||
*
|
|
||||||
* To add elements, use g_slist_append(), g_slist_prepend(),
|
|
||||||
* g_slist_insert() and g_slist_insert_sorted().
|
|
||||||
*
|
|
||||||
* To remove elements, use g_slist_remove().
|
|
||||||
*
|
|
||||||
* To find elements in the list use g_slist_last(), g_slist_next(),
|
|
||||||
* g_slist_nth(), g_slist_nth_data(), g_slist_find() and
|
|
||||||
* g_slist_find_custom().
|
|
||||||
*
|
|
||||||
* To find the index of an element use g_slist_position() and
|
|
||||||
* g_slist_index().
|
|
||||||
*
|
|
||||||
* To call a function for each element in the list use
|
|
||||||
* g_slist_foreach().
|
|
||||||
*
|
|
||||||
* To free the entire list, use g_slist_free().
|
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GSList:
|
* GSList:
|
||||||
* @data: holds the element's data, which can be a pointer to any kind
|
* @data: holds the element's data, which can be a pointer to any kind
|
||||||
|
@ -42,25 +42,6 @@
|
|||||||
#include "gutilsprivate.h"
|
#include "gutilsprivate.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:strings
|
|
||||||
* @title: Strings
|
|
||||||
* @short_description: text buffers which grow automatically
|
|
||||||
* as text is added
|
|
||||||
*
|
|
||||||
* A #GString is an object that handles the memory management of a C
|
|
||||||
* string for you. The emphasis of #GString is on text, typically
|
|
||||||
* UTF-8. Crucially, the "str" member of a #GString is guaranteed to
|
|
||||||
* have a trailing nul character, and it is therefore always safe to
|
|
||||||
* call functions such as strchr() or g_strdup() on it.
|
|
||||||
*
|
|
||||||
* However, a #GString can also hold arbitrary binary data, because it
|
|
||||||
* has a "len" member, which includes any possible embedded nul
|
|
||||||
* characters in the data. Conceptually then, #GString is like a
|
|
||||||
* #GByteArray with the addition of many convenience methods for text,
|
|
||||||
* and a guaranteed nul terminator.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GString:
|
* GString:
|
||||||
* @str: points to the character data. It may move as text is added.
|
* @str: points to the character data. It may move as text is added.
|
||||||
@ -71,7 +52,16 @@
|
|||||||
* @allocated_len: the number of bytes that can be stored in the
|
* @allocated_len: the number of bytes that can be stored in the
|
||||||
* string before it needs to be reallocated. May be larger than @len.
|
* string before it needs to be reallocated. May be larger than @len.
|
||||||
*
|
*
|
||||||
* The GString struct contains the public fields of a GString.
|
* A `GString` is an object that handles the memory management of a C string.
|
||||||
|
*
|
||||||
|
* The emphasis of `GString` is on text, typically UTF-8. Crucially, the "str" member
|
||||||
|
* of a `GString` is guaranteed to have a trailing nul character, and it is therefore
|
||||||
|
* always safe to call functions such as `strchr()` or `strdup()` on it.
|
||||||
|
*
|
||||||
|
* However, a `GString` can also hold arbitrary binary data, because it has a "len" member,
|
||||||
|
* which includes any possible embedded nul characters in the data. Conceptually then,
|
||||||
|
* `GString` is like a `GByteArray` with the addition of many convenience methods for
|
||||||
|
* text, and a guaranteed nul terminator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -42,40 +42,33 @@
|
|||||||
#include "gutilsprivate.h"
|
#include "gutilsprivate.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:string_chunks
|
* GStringChunk:
|
||||||
* @title: String Chunks
|
*
|
||||||
* @short_description: efficient storage of groups of strings
|
* `GStringChunk` provides efficient storage of groups of strings
|
||||||
*
|
*
|
||||||
* String chunks are used to store groups of strings. Memory is
|
* String chunks are used to store groups of strings. Memory is
|
||||||
* allocated in blocks, and as strings are added to the #GStringChunk
|
* allocated in blocks, and as strings are added to the `GStringChunk`
|
||||||
* they are copied into the next free position in a block. When a block
|
* they are copied into the next free position in a block. When a block
|
||||||
* is full a new block is allocated.
|
* is full a new block is allocated.
|
||||||
*
|
*
|
||||||
* When storing a large number of strings, string chunks are more
|
* When storing a large number of strings, string chunks are more
|
||||||
* efficient than using g_strdup() since fewer calls to malloc() are
|
* efficient than using [func@g_strdup] since fewer calls to `malloc()`
|
||||||
* needed, and less memory is wasted in memory allocation overheads.
|
* are needed, and less memory is wasted in memory allocation overheads.
|
||||||
*
|
*
|
||||||
* By adding strings with g_string_chunk_insert_const() it is also
|
* By adding strings with [method@GLib.StringChunk.insert_const] it is also
|
||||||
* possible to remove duplicates.
|
* possible to remove duplicates.
|
||||||
*
|
*
|
||||||
* To create a new #GStringChunk use g_string_chunk_new().
|
* To create a new `GStringChunk` use [method@GLib.StringChunk.new].
|
||||||
*
|
*
|
||||||
* To add strings to a #GStringChunk use g_string_chunk_insert().
|
* To add strings to a `GStringChunk` use [method@GLib.Stringchunk.insert].
|
||||||
*
|
*
|
||||||
* To add strings to a #GStringChunk, but without duplicating strings
|
* To add strings to a `GStringChunk`, but without duplicating strings
|
||||||
* which are already in the #GStringChunk, use
|
* which are already in the `GStringChunk`, use [method@GLib.StringChunk.insert_const].
|
||||||
* g_string_chunk_insert_const().
|
|
||||||
*
|
*
|
||||||
* To free the entire #GStringChunk use g_string_chunk_free(). It is
|
* To free the entire `GStringChunk` use [method@GLib.Stringchunk.free].
|
||||||
* not possible to free individual strings.
|
* It is not possible to free individual strings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* GStringChunk:
|
|
||||||
*
|
|
||||||
* An opaque data structure representing String Chunks.
|
|
||||||
* It should only be accessed by using the following functions.
|
|
||||||
*/
|
|
||||||
struct _GStringChunk
|
struct _GStringChunk
|
||||||
{
|
{
|
||||||
GHashTable *const_table;
|
GHashTable *const_table;
|
||||||
|
@ -27,21 +27,18 @@
|
|||||||
#include "gmessages.h"
|
#include "gmessages.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gstrvbuilder
|
* GStrvBuilder:
|
||||||
* @title: GStrvBuilder
|
|
||||||
* @short_description: Helper to create NULL-terminated string arrays.
|
|
||||||
*
|
*
|
||||||
* #GStrvBuilder is a method of easily building dynamically sized
|
* `GStrvBuilder` is a helper object to build a %NULL-terminated string arrays.
|
||||||
* NULL-terminated string arrays.
|
|
||||||
*
|
*
|
||||||
* The following example shows how to build a two element array:
|
* The following example shows how to build a two element array:
|
||||||
*
|
*
|
||||||
* |[<!-- language="C" -->
|
* ```c
|
||||||
* g_autoptr(GStrvBuilder) builder = g_strv_builder_new ();
|
* g_autoptr(GStrvBuilder) builder = g_strv_builder_new ();
|
||||||
* g_strv_builder_add (builder, "hello");
|
* g_strv_builder_add (builder, "hello");
|
||||||
* g_strv_builder_add (builder, "world");
|
* g_strv_builder_add (builder, "world");
|
||||||
* g_auto(GStrv) array = g_strv_builder_end (builder);
|
* g_auto(GStrv) array = g_strv_builder_end (builder);
|
||||||
* ]|
|
* ```
|
||||||
*
|
*
|
||||||
* Since: 2.68
|
* Since: 2.68
|
||||||
*/
|
*/
|
||||||
|
@ -30,14 +30,6 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
/**
|
|
||||||
* GStrvBuilder:
|
|
||||||
*
|
|
||||||
* A helper object to build a %NULL-terminated string array
|
|
||||||
* by appending. See g_strv_builder_new().
|
|
||||||
*
|
|
||||||
* Since: 2.68
|
|
||||||
*/
|
|
||||||
typedef struct _GStrvBuilder GStrvBuilder;
|
typedef struct _GStrvBuilder GStrvBuilder;
|
||||||
|
|
||||||
GLIB_AVAILABLE_IN_2_68
|
GLIB_AVAILABLE_IN_2_68
|
||||||
|
@ -37,43 +37,6 @@
|
|||||||
#include "gtimer.h"
|
#include "gtimer.h"
|
||||||
#include "gutils.h"
|
#include "gutils.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:thread_pools
|
|
||||||
* @title: Thread Pools
|
|
||||||
* @short_description: pools of threads to execute work concurrently
|
|
||||||
* @see_also: #GThread
|
|
||||||
*
|
|
||||||
* Sometimes you wish to asynchronously fork out the execution of work
|
|
||||||
* and continue working in your own thread. If that will happen often,
|
|
||||||
* the overhead of starting and destroying a thread each time might be
|
|
||||||
* too high. In such cases reusing already started threads seems like a
|
|
||||||
* good idea. And it indeed is, but implementing this can be tedious
|
|
||||||
* and error-prone.
|
|
||||||
*
|
|
||||||
* Therefore GLib provides thread pools for your convenience. An added
|
|
||||||
* advantage is, that the threads can be shared between the different
|
|
||||||
* subsystems of your program, when they are using GLib.
|
|
||||||
*
|
|
||||||
* To create a new thread pool, you use g_thread_pool_new().
|
|
||||||
* It is destroyed by g_thread_pool_free().
|
|
||||||
*
|
|
||||||
* If you want to execute a certain task within a thread pool,
|
|
||||||
* you call g_thread_pool_push().
|
|
||||||
*
|
|
||||||
* To get the current number of running threads you call
|
|
||||||
* g_thread_pool_get_num_threads(). To get the number of still
|
|
||||||
* unprocessed tasks you call g_thread_pool_unprocessed(). To control
|
|
||||||
* the maximal number of threads for a thread pool, you use
|
|
||||||
* g_thread_pool_get_max_threads() and g_thread_pool_set_max_threads().
|
|
||||||
*
|
|
||||||
* Finally you can control the number of unused threads, that are kept
|
|
||||||
* alive by GLib for future use. The current number can be fetched with
|
|
||||||
* g_thread_pool_get_num_unused_threads(). The maximal number can be
|
|
||||||
* controlled by g_thread_pool_get_max_unused_threads() and
|
|
||||||
* g_thread_pool_set_max_unused_threads(). All currently unused threads
|
|
||||||
* can be stopped by calling g_thread_pool_stop_unused_threads().
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DEBUG_MSG(x)
|
#define DEBUG_MSG(x)
|
||||||
/* #define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n"); */
|
/* #define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n"); */
|
||||||
|
|
||||||
@ -85,9 +48,32 @@ typedef struct _GRealThreadPool GRealThreadPool;
|
|||||||
* @user_data: the user data for the threads of this pool
|
* @user_data: the user data for the threads of this pool
|
||||||
* @exclusive: are all threads exclusive to this pool
|
* @exclusive: are all threads exclusive to this pool
|
||||||
*
|
*
|
||||||
* The #GThreadPool struct represents a thread pool. It has three
|
* The `GThreadPool` struct represents a thread pool.
|
||||||
* public read-only members, but the underlying struct is bigger,
|
*
|
||||||
* so you must not copy this struct.
|
* A thread pool is useful when you wish to asynchronously fork out the execution of work
|
||||||
|
* and continue working in your own thread. If that will happen often, the overhead of starting
|
||||||
|
* and destroying a thread each time might be too high. In such cases reusing already started
|
||||||
|
* threads seems like a good idea. And it indeed is, but implementing this can be tedious
|
||||||
|
* and error-prone.
|
||||||
|
*
|
||||||
|
* Therefore GLib provides thread pools for your convenience. An added advantage is, that the
|
||||||
|
* threads can be shared between the different subsystems of your program, when they are using GLib.
|
||||||
|
*
|
||||||
|
* To create a new thread pool, you use [method@GLib.ThreadPool.new].
|
||||||
|
* It is destroyed by [method@GLib.ThreadPool.free].
|
||||||
|
*
|
||||||
|
* If you want to execute a certain task within a thread pool, use [method@GLib.ThreadPool.push].
|
||||||
|
*
|
||||||
|
* To get the current number of running threads you call [method@GLib.ThreadPool.get_num_threads].
|
||||||
|
* To get the number of still unprocessed tasks you call [method@GLib.ThreadPool.unprocessed].
|
||||||
|
* To control the maximum number of threads for a thread pool, you use
|
||||||
|
* [method@GLib.ThreadPool.get_max_threads]. and [method@GLib.ThreadPool.set_max_threads].
|
||||||
|
*
|
||||||
|
* Finally you can control the number of unused threads, that are kept alive by GLib for future use.
|
||||||
|
* The current number can be fetched with [method@GLib.ThreadPool.get_num_unused_threads].
|
||||||
|
* The maximum number can be controlled by [method@GLib.ThreadPool.get_max_unused_threads] and
|
||||||
|
* [method@GLib.ThreadPool.set_max_unused_threads]. All currently unused threads
|
||||||
|
* can be stopped by calling [method@GLib.ThreadPool.stop_unused_threads()].
|
||||||
*/
|
*/
|
||||||
struct _GRealThreadPool
|
struct _GRealThreadPool
|
||||||
{
|
{
|
||||||
|
@ -56,22 +56,15 @@
|
|||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
#include "gmain.h"
|
#include "gmain.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:timers
|
|
||||||
* @title: Timers
|
|
||||||
* @short_description: keep track of elapsed time
|
|
||||||
*
|
|
||||||
* #GTimer records a start time, and counts microseconds elapsed since
|
|
||||||
* that time. This is done somewhat differently on different platforms,
|
|
||||||
* and can be tricky to get exactly right, so #GTimer provides a
|
|
||||||
* portable/convenient interface.
|
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GTimer:
|
* GTimer:
|
||||||
*
|
*
|
||||||
* Opaque datatype that records a start time.
|
* `GTimer` records a start time, and counts microseconds elapsed since
|
||||||
**/
|
* that time.
|
||||||
|
*
|
||||||
|
* This is done somewhat differently on different platforms, and can be
|
||||||
|
* tricky to get exactly right, so `GTimer` provides a portable/convenient interface.
|
||||||
|
*/
|
||||||
struct _GTimer
|
struct _GTimer
|
||||||
{
|
{
|
||||||
guint64 start;
|
guint64 start;
|
||||||
|
@ -53,25 +53,23 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:timezone
|
* GTimeZone:
|
||||||
* @title: GTimeZone
|
|
||||||
* @short_description: a structure representing a time zone
|
|
||||||
* @see_also: #GDateTime
|
|
||||||
*
|
*
|
||||||
* #GTimeZone is a structure that represents a time zone, at no
|
* A `GTimeZone` represents a time zone, at no particular point in time.
|
||||||
* particular point in time. It is refcounted and immutable.
|
*
|
||||||
|
* The `GTimeZone` struct is refcounted and immutable.
|
||||||
*
|
*
|
||||||
* Each time zone has an identifier (for example, ‘Europe/London’) which is
|
* Each time zone has an identifier (for example, ‘Europe/London’) which is
|
||||||
* platform dependent. See g_time_zone_new() for information on the identifier
|
* platform dependent. See [method@GLib.TimeZone.new] for information on the
|
||||||
* formats. The identifier of a time zone can be retrieved using
|
* identifier formats. The identifier of a time zone can be retrieved using
|
||||||
* g_time_zone_get_identifier().
|
* [method@GLib.TimeZone.get_identifier].
|
||||||
*
|
*
|
||||||
* A time zone contains a number of intervals. Each interval has
|
* A time zone contains a number of intervals. Each interval has an abbreviation
|
||||||
* an abbreviation to describe it (for example, ‘PDT’), an offset to UTC and a
|
* to describe it (for example, ‘PDT’), an offset to UTC and a flag indicating
|
||||||
* flag indicating if the daylight savings time is in effect during that
|
* if the daylight savings time is in effect during that interval. A time zone
|
||||||
* interval. A time zone always has at least one interval — interval 0. Note
|
* always has at least one interval — interval 0. Note that interval abbreviations
|
||||||
* that interval abbreviations are not the same as time zone identifiers
|
* are not the same as time zone identifiers (apart from ‘UTC’), and cannot be
|
||||||
* (apart from ‘UTC’), and cannot be passed to g_time_zone_new().
|
* passed to [method@GLib.TimeZone.new].
|
||||||
*
|
*
|
||||||
* Every UTC time is contained within exactly one interval, but a given
|
* Every UTC time is contained within exactly one interval, but a given
|
||||||
* local time may be contained within zero, one or two intervals (due to
|
* local time may be contained within zero, one or two intervals (due to
|
||||||
@ -84,17 +82,8 @@
|
|||||||
* that some properties (like the abbreviation) change between intervals
|
* that some properties (like the abbreviation) change between intervals
|
||||||
* without other properties changing.
|
* without other properties changing.
|
||||||
*
|
*
|
||||||
* #GTimeZone is available since GLib 2.26.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GTimeZone:
|
|
||||||
*
|
|
||||||
* #GTimeZone is an opaque structure whose members cannot be accessed
|
|
||||||
* directly.
|
|
||||||
*
|
|
||||||
* Since: 2.26
|
* Since: 2.26
|
||||||
**/
|
*/
|
||||||
|
|
||||||
/* IANA zoneinfo file format {{{1 */
|
/* IANA zoneinfo file format {{{1 */
|
||||||
|
|
||||||
|
32
glib/gtree.c
32
glib/gtree.c
@ -36,38 +36,6 @@
|
|||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
#include "gslice.h"
|
#include "gslice.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:trees-binary
|
|
||||||
* @title: Balanced Binary Trees
|
|
||||||
* @short_description: a sorted collection of key/value pairs optimized
|
|
||||||
* for searching and traversing in order
|
|
||||||
*
|
|
||||||
* The #GTree structure and its associated functions provide a sorted
|
|
||||||
* collection of key/value pairs optimized for searching and traversing
|
|
||||||
* in order. This means that most of the operations (access, search,
|
|
||||||
* insertion, deletion, ...) on #GTree are O(log(n)) in average and O(n)
|
|
||||||
* in worst case for time complexity. But, note that maintaining a
|
|
||||||
* balanced sorted #GTree of n elements is done in time O(n log(n)).
|
|
||||||
*
|
|
||||||
* To create a new #GTree use g_tree_new().
|
|
||||||
*
|
|
||||||
* To insert a key/value pair into a #GTree use g_tree_insert()
|
|
||||||
* (O(n log(n))).
|
|
||||||
*
|
|
||||||
* To remove a key/value pair use g_tree_remove() (O(n log(n))).
|
|
||||||
*
|
|
||||||
* To look up the value corresponding to a given key, use
|
|
||||||
* g_tree_lookup() and g_tree_lookup_extended().
|
|
||||||
*
|
|
||||||
* To find out the number of nodes in a #GTree, use g_tree_nnodes(). To
|
|
||||||
* get the height of a #GTree, use g_tree_height().
|
|
||||||
*
|
|
||||||
* To traverse a #GTree, calling a function for each node visited in
|
|
||||||
* the traversal, use g_tree_foreach().
|
|
||||||
*
|
|
||||||
* To destroy a #GTree, use g_tree_destroy().
|
|
||||||
**/
|
|
||||||
|
|
||||||
#define MAX_GTREE_HEIGHT 40
|
#define MAX_GTREE_HEIGHT 40
|
||||||
/* G_MAXUINT nodes will be covered by tree height of log2(G_MAXUINT) + 2. */
|
/* G_MAXUINT nodes will be covered by tree height of log2(G_MAXUINT) + 2. */
|
||||||
G_STATIC_ASSERT ((G_GUINT64_CONSTANT (1) << (MAX_GTREE_HEIGHT - 2)) >= G_MAXUINT);
|
G_STATIC_ASSERT ((G_GUINT64_CONSTANT (1) << (MAX_GTREE_HEIGHT - 2)) >= G_MAXUINT);
|
||||||
|
@ -19,43 +19,6 @@
|
|||||||
* along with this library; if not, see <http://www.gnu.org/licenses/>.
|
* along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:unicode
|
|
||||||
* @Title: Unicode Manipulation
|
|
||||||
* @Short_description: functions operating on Unicode characters and
|
|
||||||
* UTF-8 strings
|
|
||||||
* @See_also: g_locale_to_utf8(), g_locale_from_utf8()
|
|
||||||
*
|
|
||||||
* This section describes a number of functions for dealing with
|
|
||||||
* Unicode characters and strings. There are analogues of the
|
|
||||||
* traditional `ctype.h` character classification and case conversion
|
|
||||||
* functions, UTF-8 analogues of some string utility functions,
|
|
||||||
* functions to perform normalization, case conversion and collation
|
|
||||||
* on UTF-8 strings and finally functions to convert between the UTF-8,
|
|
||||||
* UTF-16 and UCS-4 encodings of Unicode.
|
|
||||||
*
|
|
||||||
* The implementations of the Unicode functions in GLib are based
|
|
||||||
* on the Unicode Character Data tables, which are available from
|
|
||||||
* [www.unicode.org](http://www.unicode.org/).
|
|
||||||
*
|
|
||||||
* * Unicode 4.0 was added in GLib 2.8
|
|
||||||
* * Unicode 4.1 was added in GLib 2.10
|
|
||||||
* * Unicode 5.0 was added in GLib 2.12
|
|
||||||
* * Unicode 5.1 was added in GLib 2.16.3
|
|
||||||
* * Unicode 6.0 was added in GLib 2.30
|
|
||||||
* * Unicode 6.1 was added in GLib 2.32
|
|
||||||
* * Unicode 6.2 was added in GLib 2.36
|
|
||||||
* * Unicode 6.3 was added in GLib 2.40
|
|
||||||
* * Unicode 7.0 was added in GLib 2.42
|
|
||||||
* * Unicode 8.0 was added in GLib 2.48
|
|
||||||
* * Unicode 9.0 was added in GLib 2.50.1
|
|
||||||
* * Unicode 10.0 was added in GLib 2.54
|
|
||||||
* * Unicode 11.10 was added in GLib 2.58
|
|
||||||
* * Unicode 12.0 was added in GLib 2.62
|
|
||||||
* * Unicode 12.1 was added in GLib 2.62
|
|
||||||
* * Unicode 13.0 was added in GLib 2.66
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -38,11 +38,9 @@
|
|||||||
#include "gwakeup.h"
|
#include "gwakeup.h"
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
* SECTION:gwakeup
|
* GWakeup:
|
||||||
* @title: GWakeup
|
|
||||||
* @short_description: portable cross-thread event signal mechanism
|
|
||||||
*
|
*
|
||||||
* #GWakeup is a simple and portable way of signaling events between
|
* `GWakeup` is a simple and portable way of signaling events between
|
||||||
* different threads in a way that integrates nicely with g_poll().
|
* different threads in a way that integrates nicely with g_poll().
|
||||||
* GLib uses it internally for cross-thread signalling in the
|
* GLib uses it internally for cross-thread signalling in the
|
||||||
* implementation of #GMainContext and #GCancellable.
|
* implementation of #GMainContext and #GCancellable.
|
||||||
@ -59,7 +57,7 @@
|
|||||||
* is implemented with a pair of pipes.
|
* is implemented with a pair of pipes.
|
||||||
*
|
*
|
||||||
* Since: 2.30
|
* Since: 2.30
|
||||||
**/
|
*/
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -124,7 +122,7 @@ struct _GWakeup
|
|||||||
gint fds[2];
|
gint fds[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/*< private >
|
||||||
* g_wakeup_new:
|
* g_wakeup_new:
|
||||||
*
|
*
|
||||||
* Creates a new #GWakeup.
|
* Creates a new #GWakeup.
|
||||||
@ -170,7 +168,7 @@ g_wakeup_new (void)
|
|||||||
return wakeup;
|
return wakeup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*< private >
|
||||||
* g_wakeup_get_pollfd:
|
* g_wakeup_get_pollfd:
|
||||||
* @wakeup: a #GWakeup
|
* @wakeup: a #GWakeup
|
||||||
* @poll_fd: a #GPollFD
|
* @poll_fd: a #GPollFD
|
||||||
@ -190,7 +188,7 @@ g_wakeup_get_pollfd (GWakeup *wakeup,
|
|||||||
poll_fd->events = G_IO_IN;
|
poll_fd->events = G_IO_IN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*< private >
|
||||||
* g_wakeup_acknowledge:
|
* g_wakeup_acknowledge:
|
||||||
* @wakeup: a #GWakeup
|
* @wakeup: a #GWakeup
|
||||||
*
|
*
|
||||||
@ -229,7 +227,7 @@ g_wakeup_acknowledge (GWakeup *wakeup)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*< private >
|
||||||
* g_wakeup_signal:
|
* g_wakeup_signal:
|
||||||
* @wakeup: a #GWakeup
|
* @wakeup: a #GWakeup
|
||||||
*
|
*
|
||||||
@ -270,7 +268,7 @@ g_wakeup_signal (GWakeup *wakeup)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*< private >
|
||||||
* g_wakeup_free:
|
* g_wakeup_free:
|
||||||
* @wakeup: a #GWakeup
|
* @wakeup: a #GWakeup
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user