gnome-devel-docs master - en to cs translation catalogue (933 entries)

note: (itstool) path: info/desc
en: Other style guides and books about organizing free software projects
cs: Pokyny k dalším stylům a knihy o organizování svobodných softwarových projektů

note: (itstool) path: page/title
en: Additional Materials
cs: Doplňující materiály

note: (itstool) path: page/p
en: Here we give you links to other materials that you may want to read. These will teach you a lot about how to work on large distributed teams of free software developers, and about good programming style in general.
cs: Zde uvádíme odkazy na další materiály, které by vás mohly zajímat. Dozvíte se v nich, jak pracovat ve velkých týmech vývojářů svobodného softwaru roztroušených po celém světě a obecně o kvalitním stylu programování.

note: (itstool) path: item/p
en: <link href="http://producingoss.com/">Producing Open Source Software</link>, by Karl Fogel. This is a truly excellent book of good practices that free software projects should follow. This is about <em>social aspects</em> of the project: how to treat contributors, how to organize and moderate communication, how to deal with non-profit foundations. If you ask yourself at any time, "how should I deal with $human_situation in the project?", this book may provide the answer.
cs: <link href="http://producingoss.com/">Producing Open Source Software</link> od Karla Fogela. Jedná se o opravdu skvělou knihu o dobrých zvycích, kterých by se měli držet projekty svobodného softwaru. Zabývá se <em>sociální stránkou</em> projektů: jak se chovat k přispěvatelům, jak organizovat a moderovat komunikaci, jak řídit neziskové nadace. Jestliže jste se někdy sami sebe zeptali: „co bych měl v projektu udělat v $SITUACE_S_LIDMI?“, dá vám tato kniha odpověď.

note: (itstool) path: item/p
en: <link href="http://www.gnu.org/prep/standards/">GNU Coding Standards</link>. This is an old document, but it still has lots of excellent advice. It talks about C coding style, issues when dealing with plug-in systems, common option names for command-line programs, conventions for Makefiles, and some very GNU-ish details like using Texinfo for documentation.
cs: <link href="http://www.gnu.org/prep/standards/">GNU Coding Standards</link>. Jedná se o starší dokument, který může ale i dnes poskytnout cenné rady. Rozebírá styl kódování v jazyce C, problémy při zacházení se zásuvnými moduly, běžné volby názvů pro programy příkazové řádky, zvyklosti pro Makefile a některými detaily okolo GNU, jako je používání Texinfo pro dokumentaci.

note: (itstool) path: item/p
en: <link href="https://www.kernel.org/doc/Documentation/process/coding-style.rst"> Linux Kernel Coding Style</link>. Explains the rationale for "big indentation", brace placement, concise but unambiguous naming, and centralized exit of functions.
cs: <link href="https://www.kernel.org/doc/Documentation/process/coding-style.rst">Linux Kernel Coding Style</link>. Vysvětluje důvody pro „velké odsazení“, umísťování závorek, stručné, ale při tom jednoznačné pojmenování a opouštění funkcí v jediném bodě.

note: (itstool) path: info/desc
en: Backwards compatibility in APIs
cs: Zpětná kompatibilita v API

note: (itstool) path: page/title
en: API stability
cs: Stabilita API

note: (itstool) path: synopsis/title
en: Summary
cs: Shrnutí

note: (itstool) path: item/p
en: Define API stability guarantees for your project. (<link xref="#stability"/>)
cs: Definujte stabilitu API zaručovanou ve vašem projektu. (<link xref="#stability"/>)

note: (itstool) path: item/p
en: Ensure version numbers are changed as appropriate when API changes. (<link xref="#versioning"/>)
cs: Zajistěte změnu čísla verze příslušně ke změnám v API. (<link xref="#versioning"/>)

note: (itstool) path: section/title
en: API and ABI
cs: API a ABI

note: (itstool) path: section/p
en: At a high level, an API – <em>Application Programming Interface</em> – is the boundary between two components when developing against them. It is closely related to an ABI – <em>Application Binary Interface</em> – which is the boundary at runtime. It defines the possible ways in which other components can interact with a component. More concretely, this normally means the C headers of a library form its API, and compiled library symbols its ABI. The difference between an API and ABI is given by compilation of the code: there are certain things in a C header, such as <code>#define</code>s, which can cause a library’s API to change without changing its ABI. But these differences are mostly academic, and for all practical purposes, API and ABI can be treated interchangeably.
cs: Ve vysokoúrovňovém programování je API (<em>Application Programming Interface</em> – rozhraní pro programování aplikací) hranicí mezi dvěma komponentami použitými při vývoji. Úzce souvisí s ABI (<em>Application Binary Interface</em> – nízkoúrovňové rozhraní aplikací), které je tou stejnou hranicí, ale za běhu. Definuje možné způsoby, kterými mohou s komponentou spolupracovat ostatní komponenty. Z praktického hlediska jsou formou API běžné hlavičkové soubory C knihovny a zkompilované knihovní symboly jsou pak ABI. Rozdíl mezi API a ABI je jen v kompilaci kódu: existují určité věci v hlavičkách C, jako třeba <code>#define</code>, které mohou způsobit, že se změní API knihovny, aniž by se změnilo ABI. Ale tyto rozdíly jsou spíše akademického rázu a v praktickém životě můžete API a ABI považovat za jinou formu téhož.

note: (itstool) path: section/p
en: Examples of API-incompatible changes to a C function would be to add a new parameter, change the function’s return type, or remove a parameter.
cs: Příkladem změn narušujících kompatibilitu API ve funkci C by bylo přidání nového parametru, změna typu vraceného funkcí nebo odstranění parametru.

note: (itstool) path: section/p
en: However, many other parts of a project can form an API. If a daemon exposes itself on D-Bus, the interfaces exported there form an API. Similarly, if a C API is exposed in higher level languages by use of GIR, the GIR file forms another API — if it changes, any higher level code using it must also change.
cs: Ale i další části projektu mohou mít formu API. Když démon vystavuje sám sebe na sběrnici D-Bus, tak tam exportovaná rozhraní mají podobu API. Obdobně, když je API C vystaveno v jazycích vyšší úrovně pomocí GIR, tvoří soubor GIR další API — když se změní, kterýkoliv kód vyšší úrovně, který jej používá, se musí změnit také.

note: (itstool) path: section/p
en: Other examples of more unusual APIs are configuration file locations and formats, and GSettings schemas. Any changes to these could require code using your library to change.
cs: Dalšími příklady méně obvyklých API jsou umístění a formáty souborů s nastavením a schémata GSettings. Jakékoliv změny v nich vyžadují, aby se změnil kód používající vaši knihovnu.

note: (itstool) path: section/title
en: Stability
cs: Stabilita

note: (itstool) path: section/p
en: API stability refers to some level of guarantee from a project that its API will only change in defined ways in the future, or will not change at all. Generally, an API is considered ‘stable’ if it commits to backwards-compatibility (defined below); but APIs could also commit to being unstable or even forwards-compatible. The purpose of API stability guarantees is to allow people to use your project from their own code without worrying about constantly updating their code to keep up with API changes. Typical API stability guarantees mean that code which is compiled against one version of a library will run without problems against all future versions of that library with the same major version number — or similarly that code which runs against a daemon will continue to run against all future versions of that daemon with the same major version number.
cs: Stabilitou API se míní určitá úroveň záruky od projektu, že se jeho API bude v budoucnu měnit jen jasně daným způsobem, případně vůbec. Obecně je API považováno za „stabilní“, pokud přináší zpětnou kompatibilitu (viz níže). Může ale být také prohlášeno za nestabilní nebo dopředně kompatibilní. Účelem záruky na stabilitu API je umožnit lidem používat váš projekt v rámci jejich vlastního programového kódu bez obav, že jej neustále budou muset aktualizovat kvůli změnám v API. Typická záruka na stabilitu API znamená, že kód, který ke kompilován vůči jedné verzi knihovny, poběží bez problémů vůči všem budoucím verzím knihovny se stejným hlavním číslem verze, nebo obdobně, že kód, který běží vůči démonovi, poběží i vůči všem budoucím verzím démona se stejným hlavním číslem verze.

note: (itstool) path: section/p
en: It is possible to apply different levels of API stability to components within a project. For example, the core functions in a library could be stable, and hence their API left unchanged in future; while the newer, less core functions could be left unstable and allowed to change wildly until the right design is found, at which point they could be marked as stable.
cs: Je možné použít pro různé komponenty projektu různé úrovně stability API. Například základní funkce v knihovně budou stabilní, takže jejich API zůstane v budoucnu beze změn, zatímco novější, méně základní funkce, by zůstaly nestabilní a mohly by se značně měnit, dokud by návrh nebyl vyladěn a pak by teprve byly označené za stabilní.

note: (itstool) path: section/p
en: Several types of stability commonly considered:
cs: Obvykle se počítá s několika běžnými typy kompatibility:

note: (itstool) path: item/title
en: Unstable
cs: Nestabilní

note: (itstool) path: item/p
en: The API could change or be removed in future.
cs: API se může v budoucnu změnit nebo může být zrušeno.

note: (itstool) path: item/title
en: Backwards compatible
cs: Zpětně kompatibilní

note: (itstool) path: item/p
en: Only changes which permit code compiled against the unmodified API to continue running against the modified API are allowed (for example, functions cannot be removed).
cs: Jsou povoleny jen změny, které umožní kódu kompilovanému vůči nezměněnému API nadále fungovat vůči změněnému API (například nesmí být odebrány funkce).

note: (itstool) path: item/title
en: Forwards compatible
cs: Dopředně kompatibilní

note: (itstool) path: item/p
en: Only changes which permit code compiled against the modified API to run against the unmodified API are allowed (for example, functions cannot be added).
cs: Jsou povoleny jen změny, které umožní kódu kompilovanému vůči změněnému API fungovat i vůči nezměněnému API (například nesmí být přidány funkce).

note: (itstool) path: item/title
en: Totally stable
cs: Zcela stabilní

note: (itstool) path: item/p
en: No changes are allowed to the API, only to the implementation.
cs: Nejsou umožněny žádné změny v API, jen v implementaci.

note: (itstool) path: section/p
en: Typically, projects commit to backwards-compatibility when they say an API is ‘stable’. Very few projects commit to total stability because it would prevent almost all further development of the project.
cs: Když nějaký projekt o svém API řekne, že je stabilní, můžete si to vyložit jako zpětnou kompatibilitu. Jen velmi málo projektů se řadí mezi úplně stabilní, protože by to bránilo skoro všem budoucím změnám v projektu.

note: (itstool) path: section/title (itstool) path: page/title
en: Versioning
cs: Číslování verzí

note: (itstool) path: section/p
en: API stability guarantees are strongly linked to project versioning; both package versioning and libtool versioning. Libtool versioning exists entirely for the purpose of tracking ABI stability, and is explained in detail on the <link href="https://autotools.io/libtool/version.html">Autotools Mythbuster</link> or <link xref="versioning"/>.
cs: Záruky stability API jsou úzce svázány s číslováním verze projektu, jak s číslováním balíčku, tak s číslováním pro libtool. Číslování verzí pro libtool existuje čistě pro účely sledování stability ABI a podrobně je vysvětleno v článku <link href="https://autotools.io/libtool/version.html">Autotools Mythbuster</link> nebo v kapitole <link xref="versioning"/>.

note: (itstool) path: section/p
en: Package versioning (<em>major.minor.micro</em>) is strongly linked to API stability: typically, the major version number is incremented when backwards-incompatible changes are made (for example, when functions are renamed, parameters are changed, or functions are removed). The minor version number is incremented when forwards-incompatible changes are made (for example, when new public API is added). The micro version number is incremented when code changes are made without modifying API. See <link xref="versioning"/> for more information.
cs: Číslování verzí balíčků (<em>hlavní.vedlejší.setinkové</em>) má úzkou souvislost se stabilitou API: typicky se hlavní číslo verze zvyšuje, když dojde ke změně ve zpětné kompatibilitě (například, když je přejmenována funkce, změněn parametr nebo odstraněna funkce). Vedlejší číslo verze se zvyšuje, když dojde ke změnám v dopředné kompatibilitě (například, když je přidáno nové veřejné API). Setinkové číslo verze se zvyšuje, když změny v kódu nijak neovlivnily API. Další informace viz <link xref="versioning"/>.

note: (itstool) path: section/p
en: API versioning is just as important for D-Bus APIs and GSettings schemas (if they are likely to change) as for C APIs. See the <link href="http://dbus.freedesktop.org/doc/dbus-api-design.html#api-versioning">documentation on D-Bus API versioning</link> for details.
cs: Číslování verzí API není důležité jen pro C, ale i pro D-Bus a schémata GSettings (pokud je předpoklad, že se budou měnit). Podrobnosti viz <link href="http://dbus.freedesktop.org/doc/dbus-api-design.html#api-versioning">dokumentace k číslování verzí API pro D-Bus</link>.

note: (itstool) path: section/p
en: For GIR APIs, their stability typically follows the C API stability, as they are generated from the C API. One complexity is that their stability additionally depends on the version of gobject-introspection used in generating the GIR, but recent versions have not changed much so this is not a major concern.
cs: U API pro GIR se jejich stabilita obvykle řídí stabilitou API v C, protože je z něj generováno. Jedinou komplikací je, že jeho stabilita závisí navíc na verzi gobject-introspection použité při generování GIR. Ta se ale v posledních verzích příliš nemění, takže to není až tak důležité.

note: (itstool) path: section/title
en: External Links
cs: Externí odkazy

note: (itstool) path: section/p
en: The topic of API stability is covered in the following articles:
cs: Tématem stability API se zabývají následující články:

note: (itstool) path: item/p
en: <link href="https://en.wikipedia.org/wiki/Application_programming_interface">Wikipedia page on APIs</link>
cs: <link href="https://cs.wikipedia.org/wiki/API">Stránka o API na Wikipedii</link>

note: (itstool) path: item/p
en: <link href="https://en.wikipedia.org/wiki/Application_binary_interface">Wikipedia page on ABIs</link>
cs: <link href="https://cs.wikipedia.org/wiki/ABI">Stránka o ABI na Wikipedii</link>

note: (itstool) path: item/p
en: <link href="http://dbus.freedesktop.org/doc/dbus-api-design.html#api-versioning">D-Bus API versioning documentation</link>
cs: <link href="http://dbus.freedesktop.org/doc/dbus-api-design.html#api-versioning">Dokumentace k číslování verzí D-Bus</link>

note: (itstool) path: info/desc
en: Use of GLib-style asynchronous methods in various situations
cs: Jak použít asynchronní metody ve stylu GLib v různých situacích

note: (itstool) path: page/title
en: Asynchronous Programming
cs: Asynchronní programování

note: (itstool) path: item/p
en: Use asynchronous calls in preference to synchronous calls or explicit use of threads (<link xref="#concepts"/>)
cs: Dávejte přednost asynchronním voláním před synchronním voláním, nebo výslovným použitím vláken (<link xref="#concepts"/>)

note: (itstool) path: item/p
en: Learn and follow the GLib pattern for declaring asynchronous APIs (<link xref="#api-pattern"/>)
cs: Naučte se a dodržujte vzory GLib pro deklarování asynchronních API (<link xref="#api-pattern"/>)

note: (itstool) path: item/p
en: Place callbacks from asynchronous functions in order down the file, so control flow is easy to follow (<link xref="#single-call"/>)
cs: Zpětná volání z asynchronních funkcí umístěte v souboru v pořadí jejich provádění, aby byl snadný přehled toku provádění kódu (<link xref="#single-call"/>)

note: (itstool) path: item/p
en: Use the presence of a <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> or <link href="https://developer.gnome.org/gio/stable/GCancellable.html"><code>GCancellable</code></link> to indicate whether an operation is ongoing (<link xref="#single-call"/>, <link xref="#gtask"/>)
cs: Používejte přítomnosti <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> nebo <link href="https://developer.gnome.org/gio/stable/GCancellable.html"><code>GCancellable</code></link> k indikaci, jestli operace probíhá (<link xref="#single-call"/>, <link xref="#gtask"/>)

note: (itstool) path: item/p
en: If running operations in parallel, track how many operations are yet to start, and how many are yet to finish — the overall operation is complete once both counts are zero (<link xref="#parallel"/>)
cs: Když spouštíte paralelní operace, sledujte kolik jich bylo spuštěno a kolik bylo dokončeno. Po dokončení celé operace by rozdíl obou hodnot měl být nula (<link xref="#parallel"/>)

note: (itstool) path: item/p
en: Separate state for operations into ‘task data’ structures for <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code>s</link>, allowing operations to be reused more easily without needing changes to global state handling (<link xref="#gtask"/>)
cs: Oddělte stavy pro operace do struktury „data úlohy“ pro objekty <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link>, aby se operace daly snáze znovu použít bez potřeby změn v globální obsluze stavu (<link xref="#gtask"/>)

note: (itstool) path: item/p
en: Consider how asynchronous methods on an object instance interact with finalization of that instance (<link xref="#lifetimes"/>)
cs: Popřemýšlejte, jak asynchronní metody v instanci objektu souvisí s finalizací instance (<link xref="#lifetimes"/>)

note: (itstool) path: section/title
en: Concepts
cs: Koncepty

note: (itstool) path: section/p
en: GLib supports <em>asynchronous</em> programming, where long-running operations can be started, run ‘in the background’, and a callback invoked when they are finished and their results are available. This is in direct contrast to <em>synchronous</em> long-running operations, which are a single function call which blocks program control flow until complete.
cs: GLib podporuje <em>asynchronní</em> programování, kdy dlouhotrvající operace mohou být spuštěny, běžet „na pozadí“ a vyvolat zpětné volání, když jsou dokončeny a jejich výsledky jsou k dispozici. Což je v přímém kontrastu se <em>synchronními</em> dlouhotrvajícími operacemi, které jsou samostatnými voláními funkcí blokujícími až do svého dokončení řízení toku programu.

note: (itstool) path: section/p
en: As discussed in <link xref="main-contexts"/> and <link xref="threading#when-to-use-threading"/>, asynchronous operations should be favoured over synchronous ones and over explicit use of threading. They do not block the main context like sychronous operations do; and are easier to use correctly than threads. They often also have a lower performance penalty than spawning a thread and sending work to it.
cs: Jak je vysvětleno v kapitolách <link xref="main-contexts"/> a <link xref="threading#when-to-use-threading"/>, asynchronní operace by měly být upřednostňovány před synchronními, i před cíleným použitím vláken. Na rozdíl od synchronních neblokují hlavní kontext a jejich správné použití je snazší než u vláken. Navíc často mají nižší dopad na výkon, než spouštění vláken.

note: (itstool) path: section/title
en: API Pattern
cs: Vzory API

note: (itstool) path: section/p
en: Asynchronous calls follow a standard pattern in GLib code. For an operation named <code>load_data</code> on the <code>File</code> class in the <code>Foo</code> namespace, there will be:
cs: Asynchronní volání se řídí standardními vzory v kódu GLib. Pro operaci nazvanou <code>load_data</code> na třídě <code>File</code> ve jmenném prostoru <code>Foo</code> to bude:

note: (itstool) path: section/p
en: The <code>…</code> parameters to <code>foo_file_load_data_async()</code> are those specific to the operation — in this case, perhaps the size of a buffer to load into. Similarly for <code>foo_file_load_data_finish()</code> they are the operation-specific return values — perhaps a location to return a content type string in this case.
cs: Parametry <code>…</code> z <code>foo_file_load_data_async()</code> jsou specifické pro operaci. V tomto případě je o velikost vyrovnávací paměti, do které se načítá. Obdobně u <code>foo_file_load_data_finish()</code> jsou specifické pro operaci návratové hodnoty, v tomto případě se jako typ řetězec vrací umístění.

note: (itstool) path: section/p
en: When <code>foo_file_load_data_async()</code> is called, it schedules the load operation in the background (as a new file descriptor on the <link xref="main-contexts"><code>GMainContext</code></link> or as a worker thread, for example), then returns without blocking.
cs: Když je zavolána funkce <code>foo_file_load_data_async()</code>, naplánuje operaci načtení na pozadí (jako nový popisovač souboru v <link xref="main-contexts"><code>GMainContext</code></link>, nebo jako pracovní vlákno), a bez blokování se vrátí.

note: (itstool) path: section/p
en: When the operation is complete, the <code>callback</code> is executed in the same <code>GMainContext</code> as the original asynchronous call. The callback is invoked <em>exactly</em> once, whether the operation succeeded or failed.
cs: Když je operace dokončena, je provedeno <code>zpětné volání</code> ve stejném <code>GMainContext</code>, jako původní asynchronní volání. Zpětné volání je zavoláno <em>právě</em> jednou, nezávisle na tom, jestli operace dopadla dobře, nebo selhala.

note: (itstool) path: section/p
en: From the callback, <code>foo_file_load_data_finish()</code> may be called by the user’s code to retrieve return values and error details, passing the <link href="https://developer.gnome.org/gio/stable/GAsyncResult.html"><code>GAsyncResult</code></link> instance which was passed to the callback.
cs: Ze zpětného volání může být uživatelským kódem zavolána funkce <code>foo_file_load_data_finish()</code> kvůli získání návratové hodnoty a podrobností o chybě, přičemž se jí předává instance <link href="https://developer.gnome.org/gio/stable/GAsyncResult.html"><code>GAsyncResult</code></link>, která byla předána zpětnému volání.

note: (itstool) path: section/title
en: Operation Lifetimes
cs: Životní průběh operace

note: (itstool) path: section/p
en: When writing asynchronous operations, it is common to write them as methods of a class. In this case, it is important to define how ongoing operations on a class instance interact with finalization of that instance. There are two approaches:
cs: Když se píše asynchronní operace, je běžné ji napsat jako metodu třídy. V tomto případě je důležité definovat, jak běžící operace nad instancí třídy komunikují s finalizací instance. Existují dva přístupy:

note: (itstool) path: item/title
en: Strong
cs: Silný

note: (itstool) path: item/p
en: The ongoing operation keeps a reference to the class instance, forcing it to remain alive for the duration of the operation. The class should provide some kind of ‘close’ or ‘cancel’ method which can be used by other classes to force cancellation of the operation and allow that instance to be finalized.
cs: Běžící operace zachovává odkaz na instanci třídy a nutí ji zůstat naživu po dobu operace. Třída může poskytovat nějaký druh metody „close“ nebo „cancel“, které mohou být použity jinou třídou k vynucení zrušení operace a umožnit této instanci finalizaci.

note: (itstool) path: item/title
en: Weak
cs: Slabý

note: (itstool) path: item/p
en: The ongoing operation does <em>not</em> keep a reference to the class instance, and the class cancels the operation (using <link href="https://developer.gnome.org/gio/stable/GCancellable.html#g-cancellable-cancel"><code>g_cancellable_cancel()</code></link>) in its dispose function.
cs: Běžící operace <em>ne</em>zachovává odkaz na instanci třídy a třída ruší operaci (pomocí <link href="https://developer.gnome.org/gio/stable/GCancellable.html#g-cancellable-cancel"><code>g_cancellable_cancel()</code></link>) ve své uvolňovací funkci.

note: (itstool) path: section/p
en: Which approach is used depends on the class’ design. A class which wraps a particular operation (perhaps a <code>MyFileTransfer</code> class, for example) might want to use the <em style="strong">weak</em> approach. A class which manages multiple network connections and asynchronous operations on them may use the <em style="strong">strong</em> approach instead. Due to incoming network connections, for example, it might not be in complete control of the scheduling of its asynchronous calls, so the weak approach would not be appropriate — any code dropping a reference to the object could not be sure it was not accidentally killing a new network connection.
cs: To, který přístup je použit, závisí na návrhu třídy. Třída, která obaluje konkrétní operaci (třída <code>MyFileTransfer</code> například), může chtít používat <em style="strong">slabý</em> přístup. Třída, která spravuje více síťových připojení a asynchronních operací nad nimi, může naopak používat <em style="strong">silný</em> přístup. Například kvůli příchozím síťovým připojením nemusí mít úplné řízení nad plánováním svých asynchronních volání, takže slabý přístup by nebyl vhodný – kód zahazující odkaz na objekt by si nemohl být jistý, jestli nešťastnou náhodou nezabije nové síťové připojení.

note: (itstool) path: section/title
en: Examples of Using Asynchronous Functions
cs: Příklad použití asynchronních funkcí

note: (itstool) path: section/p
en: It is often the case that multiple asynchronous calls need to be used to complete an operation. For example, opening a file for reading, then performing a couple of reads, and then closing the file. Or opening several network sockets in parallel and waiting until they are all open before continuing with other work. Some examples of these situations are given below.
cs: Častým případem je, že je k dokončení operace zapotřebí více asynchronních volání. Například, otevření souboru pro čtení, následně provedení několika čtení a pak zavření souboru. Nebo otevření několika síťových soketů souběžně a čekání, dokud se všechny neotevřou, než se může pokračovat s další prací se sítí. Nějaké příklady těchto situací jsou uvedeny níže.

note: (itstool) path: section/title
en: Single Operation
cs: Jedna samostatná operace

note: (itstool) path: section/p
en: A single asynchronous call requires two functions: one to start the operation, and one to complete it. In C, the demanding part of performing an asynchronous call is correctly storing state between these two functions, and handling changes to that state in the time between those two functions being called. For example, cancellation of an ongoing asynchronous call is a state change, and if not implemented carefully, any UI updates (for example) made when cancelling an operation will be undone by updates in the operation’s callback.
cs: Jedna samostatná asynchronní operace vyžaduje dvě funkce: jednu pro spuštění operace a jednu pro její dokončení. V jazyce C žádanou částí provádění asynchronního volání je správně uchovaný stav mezi těmito dvěma funkcemi a obsluha změn tohoto stavu v čase mezi zavoláním těchto dvou funkcí. Například, zrušení probíhajícího asynchronního volání je změna stavu, a když není implementováno pečlivě, aktualizace uživatelského rozhraní (například) provedené při rušení operace budou vráceny do původního stavu aktualizací ve zpětném volání operace.

note: (itstool) path: example/p
en: This example demonstrates copying a file from one location in the file system to another. The key principles demonstrated here are:
cs: Tento příklad předvádí kopírování souboru z jednoho místa v souborovém systému na druhé. Předvedené klíčové principy jsou:

note: (itstool) path: item/p
en: Placing the <code>copy_button_clicked_cb()</code> (start) and <code>copy_finish_cb()</code> (finish) functions in order by using a forward declaration for <code>copy_finish_cb()</code>. This means the control flow continues linearly down the file, rather than getting to the bottom of <code>copy_button_clicked_cb()</code> and resuming in <code>copy_finish_cb()</code> somewhere else in the file.
cs: Umístění funkcí <code>copy_button_clicked_cb()</code> (spuštění) a <code>copy_finish_cb()</code> (dokončení) v postupném pořadí pomocí dopředné deklarace pro <code>copy_finish_cb()</code>. To znamená, že řízení toku pokračuje lineárně od začátku do konce souboru se zdrojovým kódem, místo aby se <code>copy_button_clicked_cb()</code> bralo z konce a pokračovalo se na <code>copy_button_clicked_cb()</code> někde jinde v souboru.

note: (itstool) path: item/p
en: Use of a <link href="https://developer.gnome.org/gio/stable/GCancellable.html"><code>GCancellable</code></link> to allow cancelling the operation after it has started. The code in <code>cancel_button_clicked_cb()</code> is very simple: as the <code>copy_finish_cb()</code> callback is <em>guaranteed</em> to be invoked when the operation completes (even when completing early due to cancellation), all the UI and state updates for cancellation can be handled there, rather than in <code>cancel_button_clicked_cb()</code>.
cs: Používejte <link href="https://developer.gnome.org/gio/stable/GCancellable.html"><code>GCancellable</code></link>, aby se operace po té, co je spuštěna, dala zrušit. Kód v <code>cancel_button_clicked_cb()</code> je velmi jednoduchý: jelikož je <em>zaručeno</em> vyvolání zpětného volání <code>copy_finish_cb()</code>, když je operace dokončena (i když je dokončena předčasně zrušením), všechny aktualizace uživatelského rozhraní a stavu pro zrušení mohou být obslouženy zde, místo aby se tak stalo v <code>cancel_button_clicked_cb()</code>.

note: (itstool) path: item/p
en: An operation is ongoing exactly while <code>MyObjectPrivate.copy_cancellable</code> is non-<code>NULL</code>, making it easy to track running operations. Note that this means only one file copy operation can be started via <code>copy_button_clicked_cb()</code> at a time. One <code>GCancellable</code> cannot easily be used for multiple operations like this.
cs: Operace běží přesně po dobu, kdy <code>MyObjectPrivate.copy_cancellable</code> není <code>NULL</code>, díky čemuž je jednoduché sledovat běžící operace. Uvědomte si, že to znamená, že jen jedna kopírovací operace může být spuštěna přes <code>copy_button_clicked_cb()</code> v jeden okamžik. Tímto způsobem nejde jednoduše použít jednu <code>GCancellable</code> pro více operací.

note: (itstool) path: example/code
en: 
    static void
    copy_finish_cb (GObject      *source_object,
                    GAsyncResult *result,
                    gpointer      user_data);
    
    static void
    copy_button_clicked_cb (GtkButton *button
                            gpointer   user_data)
    {
      MyObjectPrivate *priv;
      GFile *source = NULL, *destination = NULL;  /* owned */
    
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Operation already in progress? */
      if (priv-&gt;copy_cancellable != NULL)
        {
          g_debug ("Copy already in progress.");
          return;
        }
    
      /* Build source and destination file paths. */
      source = g_file_new_for_path (/* some path generated from UI */);
      destination = g_file_new_for_path (/* some other path generated from UI */);
    
      /* Set up a cancellable. */
      priv-&gt;copy_cancellable = g_cancellable_new ();
    
      g_file_copy_async (source, destination, G_FILE_COPY_NONE, G_PRIORITY_DEFAULT,
                         priv-&gt;copy_cancellable, NULL, NULL,
                         copy_finish_cb, user_data);
    
      g_object_unref (destination);
      g_object_unref (source);
    
      /* Update UI to show copy is in progress. */
      …
    }
    
    static void
    copy_finish_cb (GObject      *source_object,
                    GAsyncResult *result,
                    gpointer      user_data)
    {
      MyObjectPrivate *priv;
      GFile *source;  /* unowned */
      GError *error = NULL;
    
      source = G_FILE (source_object);
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Handle completion of the operation. */
      g_file_copy_finish (source, result, &amp;error);
    
      if (error != NULL &amp;&amp;
          !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          /* Should update the UI to signal failure.
           * Ignore failure due to cancellation. */
          g_warning ("Failed to copy file: %s", error-&gt;message);
        }
    
      g_clear_error (&amp;error);
    
      /* Clear the cancellable to signify the operation has finished. */
      g_clear_object (&amp;priv-&gt;copy_cancellable);
    
      /* Update UI to show copy as complete. */
      …
    }
    
    static void
    cancel_button_clicked_cb (GtkButton *button,
                              gpointer   user_data)
    {
      MyObjectPrivate *priv;
      GFile *source = NULL, *destination = NULL;  /* owned */
    
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Operation in progress? No-op if @copy_cancellable is %NULL. */
      g_cancellable_cancel (priv-&gt;copy_cancellable);
    }
    
    static void
    my_object_dispose (GObject *obj)
    {
      MyObjectPrivate *priv;
    
      priv = my_object_get_instance_private (MY_OBJECT (obj));
    
      /* Cancel any ongoing copy operation.
       *
       * This ensures that if #MyObject is disposed part-way through a copy, the
       * callback doesn’t get invoked with an invalid #MyObject pointer. */
      g_cancellable_cancel (priv-&gt;copy_cancellable);
    
      /* Do other dispose calls here. */
      …
    
      /* Chain up. */
      G_OBJECT_CLASS (my_object_parent_class)-&gt;dispose (obj);
    }
cs: 
    static void
    copy_finish_cb (GObject      *source_object,
                    GAsyncResult *result,
                    gpointer      user_data);
    
    static void
    copy_button_clicked_cb (GtkButton *button
                            gpointer   user_data)
    {
      MyObjectPrivate *priv;
      GFile *source = NULL, *destination = NULL;  /* owned */
    
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Operace již běží? */
      if (priv-&gt;copy_cancellable != NULL)
        {
          g_debug ("Copy already in progress.");
          return;
        }
    
      /* Sestaví cestu k zdrojovému a cílovému souboru */
      source = g_file_new_for_path (/* nějaká cesta vygenerovaná z uživ. rozhraní */);
      destination = g_file_new_for_path (/* nějaká další cesta vygenerovaná z uživ. rozhraní */);
    
      /* Nastaví jako zrušitelné */
      priv-&gt;copy_cancellable = g_cancellable_new ();
    
      g_file_copy_async (source, destination, G_FILE_COPY_NONE, G_PRIORITY_DEFAULT,
                         priv-&gt;copy_cancellable, NULL, NULL,
                         copy_finish_cb, user_data);
    
      g_object_unref (destination);
      g_object_unref (source);
    
      /* Aktualizuje uživ. rozhraní, aby ukazovalo průběh */
      …
    }
    
    static void
    copy_finish_cb (GObject      *source_object,
                    GAsyncResult *result,
                    gpointer      user_data)
    {
      MyObjectPrivate *priv;
      GFile *source;  /* unowned */
      GError *error = NULL;
    
      source = G_FILE (source_object);
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Obsluha dokončení operace */
      g_file_copy_finish (source, result, &amp;error);
    
      if (error != NULL &amp;&amp;
          !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          /* Mělo by aktualizovat uživatelské rozhraní, aby oznámilo selhání
           * Ignoruje selhání kvůli zrušení */
          g_warning ("Failed to copy file: %s", error-&gt;message);
        }
    
      g_clear_error (&amp;error);
    
      /* Smaže příznak zrušitelnosti, aby dalo najevo dokončení operace */
      g_clear_object (&amp;priv-&gt;copy_cancellable);
    
      /* Aktualizace uživ. rozhraní, aby ukazovalo dokončení kopírování */
      …
    }
    
    static void
    cancel_button_clicked_cb (GtkButton *button,
                              gpointer   user_data)
    {
      MyObjectPrivate *priv;
      GFile *source = NULL, *destination = NULL;  /* owned */
    
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Operace probíhá? Žádná operace, když @copy_cancellable je %NULL. */
      g_cancellable_cancel (priv-&gt;copy_cancellable);
    }
    
    static void
    my_object_dispose (GObject *obj)
    {
      MyObjectPrivate *priv;
    
      priv = my_object_get_instance_private (MY_OBJECT (obj));
    
      /* Zrušení případné probíhající operace kopírování.
       *
       * Tím se zajistí, že když je #MyObject částečně uvolněn přes
       * kopírování, není zpětné volání vyvoláno s neplatným
       * ukazatelem na #MyObject. */\n"
      g_cancellable_cancel (priv-&gt;copy_cancellable);
    
      /* Zde proveďte případná další uvolnění */
      …
    
      /* Zřetězení */
      G_OBJECT_CLASS (my_object_parent_class)-&gt;dispose (obj);
    }

note: (itstool) path: example/p
en: For comparison, here is the same code implemented using the <em>synchronous</em> version of <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-copy"><code>g_file_copy()</code></link>. Note how the order of statements is almost identical. Cancellation cannot be supported here, as the UI is blocked from receiving ‘click’ events on the cancellation button while the copy is ongoing, so <code>NULL</code> is passed to the <code>GCancellable</code> parameter. This is the main reason why this code should <em>not</em> be used in practice.
cs: Pro srovnání, zde je ten stejný kód implementovaný pomocí <em>synchronní</em> verze <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-copy"><code>g_file_copy()</code></link>. Všimněte si, že pořadí příkazů je povětšinou stejné. Rušení v tomto případě nelez podporovat, protože uživatelské rozhraní je během kopírování blokované od příjmu události „click“ z tlačítka „Zrušit“, takže do parametru <code>GCancellable</code> předáváme <code>NULL</code>. To je také hlavní důvod, proč tento kód <em>není</em> v praxi použitelný.

note: (itstool) path: example/code
en: 
    static void
    copy_button_clicked_cb (GtkButton *button
                            gpointer   user_data)
    {
      MyObjectPrivate *priv;
      GFile *source = NULL, *destination = NULL;  /* owned */
    
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Build source and destination file paths. */
      source = g_file_new_for_path (/* some path generated from UI */);
      destination = g_file_new_for_path (/* some other path generated from UI */);
    
      g_file_copy (source, destination, G_FILE_COPY_NONE,
                   NULL  /* cancellable */, NULL, NULL,
                   &amp;error);
    
      g_object_unref (destination);
      g_object_unref (source);
    
      /* Handle completion of the operation. */
      if (error != NULL)
        {
          /* Should update the UI to signal failure.
           * Ignore failure due to cancellation. */
          g_warning ("Failed to copy file: %s", error-&gt;message);
        }
    
      g_clear_error (&amp;error);
    
      /* Update UI to show copy as complete. */
      …
    }
cs: 
    static void
    copy_button_clicked_cb (GtkButton *button
                            gpointer   user_data)
    {
      MyObjectPrivate *priv;
      GFile *source = NULL, *destination = NULL;  /* owned */
    
      priv = my_object_get_instance_private (MY_OBJECT (user_data));
    
      /* Sestaví cestu k zdrojovému a cílovému souboru */
      source = g_file_new_for_path (/* nějaká cesta vygenerovaná z uživ. rozhraní */);
      destination = g_file_new_for_path (/* nějaká další cesta vygenerovaná z uživ. rozhraní */);
    
      g_file_copy (source, destination, G_FILE_COPY_NONE,
                   NULL  /* cancellable */, NULL, NULL,
                   &amp;error);
    
      g_object_unref (destination);
      g_object_unref (source);
    
      /* Obsluha dokončení operace */
      if (error != NULL)
        {
          /* Mělo by aktualizovat uživatelské rozhraní, aby oznámilo selhání
           * Ignoruje selhání kvůli zrušení */
          g_warning ("Failed to copy file: %s", error-&gt;message);
        }
    
      g_clear_error (&amp;error);
    
      /* Aktualizace uživ. rozhraní, aby ukazovalo dokončení kopírování */
      …
    }

note: (itstool) path: section/title
en: Operations in Series
cs: Operace prováděné sériově

note: (itstool) path: section/p
en: A common situation is to run multiple asynchronous operations in series, when each operation depends on the previous one completing.
cs: Běžnou situací je spuštění více asynchronních operací po sobě, když každá z operací závisí na dokončení předchozí.

note: (itstool) path: example/p
en: In this example, the application reads a socket address from a file, opens a connection to that address, reads a message, and then finishes.
cs: V tomto příkladu aplikace čte adresu soketu ze souboru, otevře připojení na tuto adresu, přečte zprávu a pak skončí.

note: (itstool) path: example/p
en: Key points in this example are:
cs: Klíčové body v tomto příkladu:

note: (itstool) path: item/p
en: Each callback is numbered consistently, and they are all placed in order in the file so the code follows sequentially.
cs: Jednotlivá zpětná volání jsou jednotně očíslovaná a ve správném pořadí umístěná v souboru se zdrojovým kódem, takže kód je provádět postupně ve stejném pořadí.

note: (itstool) path: item/p
en: As in <link xref="#single-call"/>, a single <code>GCancellable</code> indicates that the series of operations is ongoing. Cancelling it aborts the entire sequence.
cs: Stejně jako v kapitole <link xref="#single-call"/>, jediné <code>GCancellable</code> indikuje, že běží série operací. Její zrušení přeruší celou posloupnost.

note: (itstool) path: item/p
en: As in <link xref="#single-call"/>, the pending operation is cancelled if the owning <code>MyObject</code> instance is disposed, to prevent callbacks being called later with an invalid <code>MyObject</code> pointer.
cs: Stejně jako v <link xref="#single-call"/> jsou čekající operace zrušeny, když je vlastnící instance <code>MyObject</code> uvolněna, aby se zabránilo pozdějšímu zavolání zpětného volání s neplatným ukazatelem <code>MyObject</code>.

note: (itstool) path: example/p
en: <link xref="#gtask"/> gives a version of this example wrapped in a <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> for convenience.
cs: <link xref="#gtask"/> poskytuje verzi tohoto příkladu obalenou pro pohodlí do <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link>.

note: (itstool) path: example/code
en: 
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    
    static void
    connect_to_server (MyObject *self)
    {
      MyObjectPrivate *priv;
      GFile *address_file = NULL;  /* owned */
    
      priv = my_object_get_instance_private (self);
    
      if (priv-&gt;connect_cancellable != NULL)
        {
          /* Already connecting. */
          return;
        }
    
      /* Set up a cancellable. */
      priv-&gt;connect_cancellable = g_cancellable_new ();
    
      /* Read the socket address. */
      address_file = build_address_file ();
      g_file_load_contents_async (address_file, priv-&gt;connect_cancellable,
                                  connect_to_server_cb1, self);
      g_object_unref (address_file);
    }
    
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GFile *address_file;  /* unowned */
      gchar *address = NULL;  /* owned */
      gsize address_size = 0;
      GInetAddress *inet_address = NULL;  /* owned */
      GInetSocketAddress *inet_socket_address = NULL;  /* owned */
      guint16 port = 123;
      GSocketClient *socket_client = NULL;  /* owned */
      GError *error = NULL;
    
      address_file = G_FILE (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Finish loading the address. */
      g_file_load_contents_finish (address_file, result, &amp;address,
                                   &amp;address_size, NULL, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Parse the address. */
      inet_address = g_inet_address_new_from_string (address);
    
      if (inet_address == NULL)
        {
          /* Error. */
          g_set_error (&amp;error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       "Invalid address ‘%s’.", address);
          goto done;
        }
    
      inet_socket_address = g_inet_socket_address_new (inet_address, port);
    
      /* Connect to the given address. */
      socket_client = g_socket_client_new ();
    
      g_socket_client_connect_async (socket_client,
                                     G_SOCKET_CONNECTABLE (inet_socket_address),
                                     priv-&gt;connect_cancellable,
                                     connect_to_server_cb2,
                                     self);
    
    done:
      if (error != NULL)
        {
          /* Stop the operation. */
          if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
            {
              g_warning ("Failed to load server address: %s", error-&gt;message);
            }
    
          g_clear_object (&amp;priv-&gt;connect_cancellable);
          g_error_free (error);
        }
    
      g_free (address);
      g_clear_object (&amp;inet_address);
      g_clear_object (&amp;inet_socket_address);
      g_clear_object (&amp;socket_client);
    }
    
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GSocketClient *socket_client;  /* unowned */
      GSocketConnection *connection = NULL;  /* owned */
      GInputStream *input_stream;  /* unowned */
      GError *error = NULL;
    
      socket_client = G_SOCKET_CLIENT (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Finish connecting to the socket. */
      connection = g_socket_client_connect_finish (socket_client, result,
                                                   &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Store a reference to the connection so it is kept open while we read from
       * it: #GInputStream does not keep a reference to a #GIOStream which contains
       * it. */
      priv-&gt;connection = g_object_ref (connection);
    
      /* Read a message from the connection. This uses a single buffer stored in
       * #MyObject, meaning that only one connect_to_server() operation can run at
       * any time. The buffer could instead be allocated dynamically if this is a
       * problem. */
      input_stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
    
      g_input_stream_read_async (input_stream,
                                 priv-&gt;message_buffer,
                                 sizeof (priv-&gt;message_buffer),
                                 G_PRIORITY_DEFAULT, priv-&gt;connect_cancellable,
                                 connect_to_server_cb3, self);
    
    done:
      if (error != NULL)
        {
          /* Stop the operation. */
          if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
            {
              g_warning ("Failed to connect to server: %s", error-&gt;message);
            }
    
          g_clear_object (&amp;priv-&gt;connect_cancellable);
          g_clear_object (&amp;priv-&gt;connection);
          g_error_free (error);
        }
    
      g_clear_object (&amp;connection);
    }
    
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GInputStream *input_stream;  /* unowned */
      gssize len = 0;
      GError *error = NULL;
    
      input_stream = G_INPUT_STREAM (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Finish reading from the socket. */
      len = g_input_stream_read_finish (input_stream, result, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Handle the message. */
      g_assert_cmpint (len, &gt;=, 0);
      g_assert_cmpuint ((gsize) len, &lt;=, sizeof (priv-&gt;message_buffer));
    
      handle_received_message (self, priv-&gt;message_buffer, len, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
    done:
      /* Unconditionally mark the operation as finished.
       *
       * The streams should automatically close as this
       * last reference is dropped. */
      g_clear_object (&amp;priv-&gt;connect_cancellable);
      g_clear_object (&amp;priv-&gt;connection);
    
      if (error != NULL)
        {
          /* Warn about the error. */
          if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
            {
              g_warning ("Failed to read from the server: %s", error-&gt;message);
            }
    
          g_error_free (error);
        }
    }
    
    static void
    my_object_dispose (GObject *obj)
    {
      MyObjectPrivate *priv;
    
      priv = my_object_get_instance_private (MY_OBJECT (obj));
    
      /* Cancel any ongoing connection operations.
       *
       * This ensures that if #MyObject is disposed part-way through the
       * connect_to_server() sequence of operations, the sequence gets cancelled and
       * doesn’t continue with an invalid #MyObject pointer. */
      g_cancellable_cancel (priv-&gt;connect_cancellable);
    
      /* Do other dispose calls here. */
      …
    
      /* Chain up. */
      G_OBJECT_CLASS (my_object_parent_class)-&gt;dispose (obj);
    }
cs: 
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    
    static void
    connect_to_server (MyObject *self)
    {
      MyObjectPrivate *priv;
      GFile *address_file = NULL;  /* owned */
    
      priv = my_object_get_instance_private (self);
    
      if (priv-&gt;connect_cancellable != NULL)
        {
          /* Již se připojuje */
          return;
        }
    
      /* Nastavení jako zrušitelné */
      priv-&gt;connect_cancellable = g_cancellable_new ();
    
      /* Čtení adresy soketu */
      address_file = build_address_file ();
      g_file_load_contents_async (address_file, priv-&gt;connect_cancellable,
                                  connect_to_server_cb1, self);
      g_object_unref (address_file);
    }
    
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GFile *address_file;  /* unowned */
      gchar *address = NULL;  /* owned */
      gsize address_size = 0;
      GInetAddress *inet_address = NULL;  /* owned */
      GInetSocketAddress *inet_socket_address = NULL;  /* owned */
      guint16 port = 123;
      GSocketClient *socket_client = NULL;  /* owned */
      GError *error = NULL;
    
      address_file = G_FILE (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Dokončení načítání adresy */
      g_file_load_contents_finish (address_file, result, &amp;address,
                                   &amp;address_size, NULL, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Zpracování adresy */
      inet_address = g_inet_address_new_from_string (address);
    
      if (inet_address == NULL)
        {
          /* Chyba */
          g_set_error (&amp;error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       "Invalid address ‘%s’.", address);
          goto done;
        }
    
      inet_socket_address = g_inet_socket_address_new (inet_address, port);
    
      /* Připojení na zadanou adresu */
      socket_client = g_socket_client_new ();
    
      g_socket_client_connect_async (socket_client,
                                     G_SOCKET_CONNECTABLE (inet_socket_address),
                                     priv-&gt;connect_cancellable,
                                     connect_to_server_cb2,
                                     self);
    
    done:
      if (error != NULL)
        {
          /* Zastavení operace */
          if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
            {
              g_warning ("Failed to load server address: %s", error-&gt;message);
            }
    
          g_clear_object (&amp;priv-&gt;connect_cancellable);
          g_error_free (error);
        }
    
      g_free (address);
      g_clear_object (&amp;inet_address);
      g_clear_object (&amp;inet_socket_address);
      g_clear_object (&amp;socket_client);
    }
    
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GSocketClient *socket_client;  /* unowned */
      GSocketConnection *connection = NULL;  /* owned */
      GInputStream *input_stream;  /* unowned */
      GError *error = NULL;
    
      socket_client = G_SOCKET_CLIENT (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Dokončení připojování k soketu */
      connection = g_socket_client_connect_finish (socket_client, result,
                                                   &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Uchování odkazu na připojení, takže je udržované otevřené po dobu co z něj
       * čteme: #GInputStream neudržuje odkaz na #GIOStream, který jej obsahuje */
      priv-&gt;connection = g_object_ref (connection);
    
      /* Čtení zprávy z připojení. Používá jedinou vyrovnávací paměť uchovanou v
       * #MyObject, což znamená, že v danou chvíli může běžet jen jediná operace
       * connect_to_server(). Pokud je to problém , může být vyrovnávací paměť
       * místo toho alokována dynamicky. */
      input_stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
    
      g_input_stream_read_async (input_stream,
                                 priv-&gt;message_buffer,
                                 sizeof (priv-&gt;message_buffer),
                                 G_PRIORITY_DEFAULT, priv-&gt;connect_cancellable,
                                 connect_to_server_cb3, self);
    
    done:
      if (error != NULL)
        {
          /* Zastavení operace */
          if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
            {
              g_warning ("Failed to connect to server: %s", error-&gt;message);
            }
    
          g_clear_object (&amp;priv-&gt;connect_cancellable);
          g_clear_object (&amp;priv-&gt;connection);
          g_error_free (error);
        }
    
      g_clear_object (&amp;connection);
    }
    
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GInputStream *input_stream;  /* unowned */
      gssize len = 0;
      GError *error = NULL;
    
      input_stream = G_INPUT_STREAM (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Dokončení čtení ze soketu */
      len = g_input_stream_read_finish (input_stream, result, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Obsluha zprávy */
      g_assert_cmpint (len, &gt;=, 0);
      g_assert_cmpuint ((gsize) len, &lt;=, sizeof (priv-&gt;message_buffer));
    
      handle_received_message (self, priv-&gt;message_buffer, len, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
    done:
      /* Nepodmíněné označení operace za dokončenou.
       *
       * Proud dat by se měl automaticky zavřít, protože
       * je zahozen poslední odkaz. */
      g_clear_object (&amp;priv-&gt;connect_cancellable);
      g_clear_object (&amp;priv-&gt;connection);
    
      if (error != NULL)
        {
          /* Varování o chybě */
          if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
            {
              g_warning ("Failed to read from the server: %s", error-&gt;message);
            }
    
          g_error_free (error);
        }
    }
    
    static void
    my_object_dispose (GObject *obj)
    {
      MyObjectPrivate *priv;
    
      priv = my_object_get_instance_private (MY_OBJECT (obj));
    
      /* Zrušení případných probíhajících operací mazání.
       *
       * Tím se zajistí, že když je #MyObject částečně uvolněn přes
       * sadu operací delete_files(), sada obdrží zrušení a nepokračuje
       * s neplatným ukazatelem na #MyObject. */
      g_cancellable_cancel (priv-&gt;connect_cancellable);
    
      /* Zde proveďte případná další uvolnění */
      …
    
      /* Zřetězení */
      G_OBJECT_CLASS (my_object_parent_class)-&gt;dispose (obj);
    }

note: (itstool) path: section/title
en: Operations in Parallel
cs: Operace prováděné paralelně

note: (itstool) path: section/p
en: Another common situation is to run multiple asynchronous operations in parallel, considering the overall operation complete when all its constituents are complete.
cs: Jinou běžnou situací je spustit více asynchronních operací souběžně s předpokladem, že celková operace bude dokončena, jakmile všechny její součásti doběhnou.

note: (itstool) path: example/p
en: In this example, the application deletes multiple files in parallel.
cs: V tomto příkladu aplikace maže souběžně několik souborů.

note: (itstool) path: item/p
en: The number of pending asynchronous operations (ones which have started but not yet finished) is tracked as <code>n_deletions_pending</code>. The <code>delete_files_cb()</code> callback only considers the entire operation complete once this reaches zero.
cs: Počet čekajících asynchronních operací (tj. těch, které byly spuštěny a ještě nedoběhly) je sledován v <code>n_deletions_pending</code>. Zpětné volání <code>delete_files_cb()</code> bere celkovou operaci za dokončenou, až když tato hodnota dosáhne nuly.

note: (itstool) path: item/p
en: <code>n_deletions_to_start</code> tracks deletion operations being started, in case <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-delete-async"><code>g_file_delete_async()</code></link> manages to use a fast path and complete synchronously (without blocking).
cs: <code>n_deletions_to_start</code> sleduje spouštění operací mazání, v případě <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-delete-async"><code>g_file_delete_async()</code></link> spravuje použití rychlé cesty a dokončení synchronně (bez blokování).

note: (itstool) path: item/p
en: As in <link xref="#single-call"/>, all pending deletions are cancelled if the owning <code>MyObject</code> instance is disposed, to prevent callbacks being called later with an invalid <code>MyObject</code> pointer.
cs: Stejně jako v <link xref="#single-call"/>, jsou všechna čekající mazání zrušena v situaci, kdy je vlastnící instance <code>MyObject</code> uvolněna, aby se zabránilo pozdějšímu zavolání zpětného volání s neplatným ukazatelem <code>MyObject</code>.

note: (itstool) path: example/code
en: 
    static void
    delete_files_cb (GObject      *source_object,
                     GAsyncResult *result,
                     gpointer      user_data);
    
    static void
    delete_files (MyObject *self,
                  GPtrArray/*&lt;owned GFile*&gt;&gt;*/ *files)
    {
      MyObjectPrivate *priv;
      GFile *address_file = NULL;  /* owned */
    
      priv = my_object_get_instance_private (self);
    
      /* Set up a cancellable if no operation is ongoing already. */
      if (priv-&gt;delete_cancellable == NULL)
        {
          priv-&gt;delete_cancellable = g_cancellable_new ();
          priv-&gt;n_deletions_pending = 0;
          priv-&gt;n_deletions_total = 0;
        }
    
      /* Update internal state, and temporarily set @n_deletions_to_start. This is
       * used in delete_files_cb() to avoid indicating the overall operation has
       * completed while deletions are still being started. This can happen if
       * g_file_delete_async() completes synchronously, for example if there’s a
       * non-blocking fast path for the given file system. */
      priv-&gt;n_deletions_pending += files-&gt;len;
      priv-&gt;n_deletions_total += files-&gt;len;
      priv-&gt;n_deletions_to_start = files-&gt;len;
    
      /* Update the UI to indicate the files are being deleted. */
      update_ui_to_show_progress (self,
                                  priv-&gt;n_deletions_pending,
                                  priv-&gt;n_deletions_total);
    
      /* Start all the deletion operations in parallel. They share the same
       * #GCancellable. */
      for (i = 0; i &lt; files-&gt;len; i++)
        {
          GFile *file = files-&gt;pdata[i];
    
          priv-&gt;n_deletions_to_start--;
          g_file_delete_async (file, G_PRIORITY_DEFAULT, priv-&gt;delete_cancellable,
                               delete_files_cb, self);
        }
    }
    
    static void
    delete_files_cb (GObject      *source_object,
                     GAsyncResult *result,
                     gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GFile *file;  /* unowned */
      GError *error = NULL;
    
      file = G_FILE (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Finish deleting the file. */
      g_file_delete_finish (file, result, &amp;error);
    
      if (error != NULL &amp;&amp;
          !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_warning ("Error deleting file: %s", error-&gt;message);
        }
    
      g_clear_error (&amp;error);
    
      /* Update the internal state. */
      g_assert_cmpuint (priv-&gt;n_deletions_pending, &gt;, 0);
      priv-&gt;n_deletions_pending--;
    
      /* Update the UI to show progress. */
      update_ui_to_show_progress (self,
                                  priv-&gt;n_deletions_pending,
                                  priv-&gt;n_deletions_total);
    
      /* If all deletions have completed, and no more are being started,
       * update the UI to show completion. */
      if (priv-&gt;n_deletions_pending == 0 &amp;&amp; priv-&gt;n_deletions_to_start == 0)
        {
          update_ui_to_show_completion (self);
    
          /* Clear the operation state. */
          g_clear_object (&amp;priv-&gt;delete_cancellable);
          priv-&gt;n_deletions_total = 0;
        }
    }
    
    static void
    my_object_dispose (GObject *obj)
    {
      MyObjectPrivate *priv;
    
      priv = my_object_get_instance_private (MY_OBJECT (obj));
    
      /* Cancel any ongoing deletion operations.
       *
       * This ensures that if #MyObject is disposed part-way through the
       * delete_files() set of operations, the set gets cancelled and
       * doesn’t continue with an invalid #MyObject pointer. */
      g_cancellable_cancel (priv-&gt;delete_cancellable);
    
      /* Do other dispose calls here. */
      …
    
      /* Chain up. */
      G_OBJECT_CLASS (my_object_parent_class)-&gt;dispose (obj);
    }
cs: 
    static void
    delete_files_cb (GObject      *source_object,
                     GAsyncResult *result,
                     gpointer      user_data);
    
    static void
    delete_files (MyObject *self,
                  GPtrArray/*&lt;owned GFile*&gt;&gt;*/ *files)
    {
      MyObjectPrivate *priv;
      GFile *address_file = NULL;  /* owned */
    
      priv = my_object_get_instance_private (self);
    
      /* Nastavení jako zrušitelné, pokud již neběží žádná operace */
      if (priv-&gt;delete_cancellable == NULL)
        {
          priv-&gt;delete_cancellable = g_cancellable_new ();
          priv-&gt;n_deletions_pending = 0;
          priv-&gt;n_deletions_total = 0;
        }
    
      /* Aktualizace interního stavu a dočasné nastavení @n_deletions_to_start.
       * To se používá v delete_files_cb(), aby se předešlo oznámení, že je celá
       * operace dokončená, zatím co ona stále běží. To by se mohlo stát, když
       * g_file_delete_async() doběhne synchronně, například, když existuje
       * neblokující rychlá cesta pro zadaný souborový systém. */
      priv-&gt;n_deletions_pending += files-&gt;len;
      priv-&gt;n_deletions_total += files-&gt;len;
      priv-&gt;n_deletions_to_start = files-&gt;len;
    
      /* Aktulazice uživatelského rozhraní, aby dalo najevo, že je soubor mazán */
      update_ui_to_show_progress (self,
                                  priv-&gt;n_deletions_pending,
                                  priv-&gt;n_deletions_total);
    
      /* Začne souběžně všechny operace mazání. Sdílejí stejný #GCancellable. */
      for (i = 0; i &lt; files-&gt;len; i++)
        {
          GFile *file = files-&gt;pdata[i];
    
          priv-&gt;n_deletions_to_start--;
          g_file_delete_async (file, G_PRIORITY_DEFAULT, priv-&gt;delete_cancellable,
                               delete_files_cb, self);
        }
    }
    
    static void
    delete_files_cb (GObject      *source_object,
                     GAsyncResult *result,
                     gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GFile *file;  /* unowned */
      GError *error = NULL;
    
      file = G_FILE (source_object);
      self = MY_OBJECT (user_data);
      priv = my_object_get_instance_private (self);
    
      /* Dokončení mazání souboru */
      g_file_delete_finish (file, result, &amp;error);
    
      if (error != NULL &amp;&amp;
          !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_warning ("Error deleting file: %s", error-&gt;message);
        }
    
      g_clear_error (&amp;error);
    
      /* Aktualizace interního stavu */
      g_assert_cmpuint (priv-&gt;n_deletions_pending, &gt;, 0);
      priv-&gt;n_deletions_pending--;
    
      /* Aktualizace uživatelského rozhraní, aby ukazovalo průběh */
      update_ui_to_show_progress (self,
                                  priv-&gt;n_deletions_pending,
                                  priv-&gt;n_deletions_total);
    
      /* Jestliže je všechno mazání dokončeno a žádné další nezačíná, aktualizuje se,
       * uživatelské rozhraní, aby ukazovalo, že je vše dokončeno. */
      if (priv-&gt;n_deletions_pending == 0 &amp;&amp; priv-&gt;n_deletions_to_start == 0)
        {
          update_ui_to_show_completion (self);
    
          /* Vyčištění stavu operace */
          g_clear_object (&amp;priv-&gt;delete_cancellable);
          priv-&gt;n_deletions_total = 0;
        }
    }
    
    static void
    my_object_dispose (GObject *obj)
    {
      MyObjectPrivate *priv;
    
      priv = my_object_get_instance_private (MY_OBJECT (obj));
    
      /* Zrušení případných probíhajících operací mazání.
       *
       * Tím se zajistí, že když je #MyObject částečně uvolněn přes
       * sadu operací delete_files(), sada obdrží zrušení a nepokračuje
       * s neplatným ukazatelem na #MyObject. */
      g_cancellable_cancel (priv-&gt;delete_cancellable);
    
      /* Zde proveďte případná další uvolnění */
      …
    
      /* Zřetězení */
      G_OBJECT_CLASS (my_object_parent_class)-&gt;dispose (obj);
    }

note: (itstool) path: section/title
en: Wrapping with <code>GTask</code>
cs: Obalení pomocí <code>GTask</code>

note: (itstool) path: section/p
en: Often when an asynchronous operation (or set of operations) becomes more complex, it needs associated state. This is typically stored in a custom structure — but defining a new structure to store the standard callback, user data and cancellable tuple is laborious. <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> eases this by providing a standardized way to wrap all three, plus extra custom ‘task data’.
cs: Asynchronní operace (nebo sady operací) často, když se stanou více komplexními, potřebují přiřazený stav. Ten bývá typicky uchován ve vlastní struktuře, ale definování nové struktury pro uchování standardního zpětného volání, uživatelských dat a n-tice zrušitelných je pracné. <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> to zjednodušuje poskytnutím standardního způsobu obalení všech tří věcí, plus navíc vlastními „daty úlohy“.

note: (itstool) path: section/p
en: The use of a <code>GTask</code> can replace the use of a <link href="https://developer.gnome.org/gio/stable/GCancellable.html"><code>GCancellable</code></link> for indicating whether an operation is ongoing.
cs: Použití <code>GTask</code> může nahradit použití <link href="https://developer.gnome.org/gio/stable/GCancellable.html"><code>GCancellable</code></link> pro indikaci, jestli běží nějaká operace.

note: (itstool) path: example/p
en: This example is functionally the same as <link xref="#series"/>, but refactored to use a <code>GTask</code> to wrap the sequence of operations.
cs: Tento příklad se z hlediska funkcionality shoduje s <link xref="#series"/>, ale je přepracován tak, aby používal <code>GTask</code> k obalení posloupnosti operací.

note: (itstool) path: item/p
en: State which was in <code>MyObjectPrivate</code> in <link xref="#series"/> is now in the <code>ConnectToServerData</code> closure, which is set as the ‘task data’ of the <code>GTask</code> representing the overall operation. This means it’s automatically freed after the operation returns.
cs: Stav, který byl v <link xref="#series"/> v <code>MyObjectPrivate</code>, je nyní uzavřen v <code>ConnectToServerData</code>, který je nastaven jako „daty úlohy“ objektu <code>GTask</code> představujícího celkovou operaci. To znamená, že je automaticky uvolněn po návratu z operace.

note: (itstool) path: item/p
en: Furthermore, this means that manipulations of <code>MyObjectPrivate</code> state are limited to the start and end of the sequence of operations, so reusing the task in different situations becomes easier — for example, it is now a lot easier to support running multiple such tasks in parallel.
cs: Navíc to znamená, že zacházení se stavem <code>MyObjectPrivate</code> je omezeno na začátek a konec posloupnosti operací, takže znovupoužití úlohy v jiné situaci se stává snazší. Například je nyní mnohem snazší podporovat běh více takovýchto úloh souběžně.

note: (itstool) path: item/p
en: As the <code>GTask</code> holds a reference to <code>MyObject</code>, it is impossible for the object to be disposed while the sequence of operations is ongoing, so the <code>my_object_dispose()</code> code has been removed. Instead, a <code>my_object_close()</code> method exists to allow any pending operations can be cancelled so <code>MyObject</code> can be disposed when desired.
cs: Protože <code>GTask</code> udržuje odkaz na <code>MyObject</code>, není objekt možné uvolnit, když probíhá posloupnost operací. Proto byl kód <code>my_object_dispose()</code> odstraněn. Místo něj je teď metoda <code>my_object_close()</code>, která umožňuje zrušení případných čekajících operací, takže <code>MyObject</code> může být v případě potřeby uvolněn.

note: (itstool) path: example/code
en: 
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    
    typedef struct {
      GSocketConnection *connection;  /* nullable; owned */
      guint8 message_buffer[128];
    } ConnectToServerData;
    
    static void
    connect_to_server_data_free (ConnectToServerData *data)
    {
      g_clear_object (&amp;data-&gt;connection);
    }
    
    void
    my_object_connect_to_server_async (MyObject            *self,
                                       GCancellable        *cancellable,
                                       GAsyncReadyCallback  callback,
                                       gpointer             user_data)
    {
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      ConnectToServerData *data = NULL;  /* owned */
      GFile *address_file = NULL;  /* owned */
    
      g_return_if_fail (MY_IS_OBJECT (self));
      g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
    
      priv = my_object_get_instance_private (self);
    
      if (priv-&gt;connect_task != NULL)
        {
          g_task_report_new_error (self, callback, user_data, NULL,
                                   G_IO_ERROR, G_IO_ERROR_PENDING,
                                   "Already connecting to the server.");
          return;
        }
    
      /* Set up a cancellable. */
      if (cancellable != NULL)
        {
          g_object_ref (cancellable);
        }
      else
        {
          cancellable = g_cancellable_new ();
        }
    
      /* Set up the task. */
      task = g_task_new (self, cancellable, callback, user_data);
      g_task_set_check_cancellable (task, FALSE);
    
      data = g_malloc0 (sizeof (ConnectToServerData));
      g_task_set_task_data (task, data,
                            (GDestroyNotify) connect_to_server_data_free);
    
      g_object_unref (cancellable);
    
      priv-&gt;connect_task = g_object_ref (task);
    
      /* Read the socket address. */
      address_file = build_address_file ();
      g_file_load_contents_async (address_file, g_task_get_cancellable (task),
                                  connect_to_server_cb1, g_object_ref (task));
      g_object_unref (address_file);
    
      g_clear_object (&amp;task);
    }
    
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      GFile *address_file;  /* unowned */
      gchar *address = NULL;  /* owned */
      gsize address_size = 0;
      GInetAddress *inet_address = NULL;  /* owned */
      GInetSocketAddress *inet_socket_address = NULL;  /* owned */
      guint16 port = 123;
      GSocketClient *socket_client = NULL;  /* owned */
      GError *error = NULL;
    
      address_file = G_FILE (source_object);
      task = G_TASK (user_data);
      self = g_task_get_source_object (task);
      priv = my_object_get_instance_private (self);
    
      /* Finish loading the address. */
      g_file_load_contents_finish (address_file, result, &amp;address,
                                   &amp;address_size, NULL, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Parse the address. */
      inet_address = g_inet_address_new_from_string (address);
    
      if (inet_address == NULL)
        {
          /* Error. */
          g_set_error (&amp;error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       "Invalid address ‘%s’.", address);
          goto done;
        }
    
      inet_socket_address = g_inet_socket_address_new (inet_address, port);
    
      /* Connect to the given address. */
      socket_client = g_socket_client_new ();
    
      g_socket_client_connect_async (socket_client,
                                     G_SOCKET_CONNECTABLE (inet_socket_address),
                                     g_task_get_cancellable (task),
                                     connect_to_server_cb2,
                                     g_object_ref (task));
    
    done:
      if (error != NULL)
        {
          /* Stop the operation and propagate the error. */
          g_clear_object (&amp;priv-&gt;connect_task);
          g_task_return_error (task, error);
        }
    
      g_free (address);
      g_clear_object (&amp;inet_address);
      g_clear_object (&amp;inet_socket_address);
      g_clear_object (&amp;socket_client);
      g_clear_object (&amp;task);
    }
    
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      ConnectToServerData *data;  /* unowned */
      GSocketClient *socket_client;  /* unowned */
      GSocketConnection *connection = NULL;  /* owned */
      GInputStream *input_stream;  /* unowned */
      GError *error = NULL;
    
      socket_client = G_SOCKET_CLIENT (source_object);
      task = G_TASK (user_data);
      data = g_task_get_task_data (task);
      self = g_task_get_source_object (task);
      priv = my_object_get_instance_private (self);
    
      /* Finish connecting to the socket. */
      connection = g_socket_client_connect_finish (socket_client, result,
                                                   &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Store a reference to the connection so it is kept open while we read from
       * it: #GInputStream does not keep a reference to a #GIOStream which contains
       * it. */
      data-&gt;connection = g_object_ref (connection);
    
      /* Read a message from the connection. As the buffer is allocated as part of
       * the per-task @data, multiple tasks can run concurrently. */
      input_stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
    
      g_input_stream_read_async (input_stream,
                                 data-&gt;message_buffer,
                                 sizeof (data-&gt;message_buffer),
                                 G_PRIORITY_DEFAULT, g_task_get_cancellable (task),
                                 connect_to_server_cb3, g_object_ref (task));
    
    done:
      if (error != NULL)
        {
          /* Stop the operation and propagate the error. */
          g_clear_object (&amp;priv-&gt;connect_task);
          g_task_return_error (task, error);
        }
    
      g_clear_object (&amp;connection);
      g_clear_object (&amp;task);
    }
    
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      ConnectToServerData *data;  /* unowned */
      GInputStream *input_stream;  /* unowned */
      gssize len = 0;
      GError *error = NULL;
    
      input_stream = G_INPUT_STREAM (source_object);
      task = G_TASK (user_data);
      data = g_task_get_task_data (task);
      self = g_task_get_source_object (task);
      priv = my_object_get_instance_private (self);
    
      /* Finish reading from the socket. */
      len = g_input_stream_read_finish (input_stream, result, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Handle the message. */
      g_assert_cmpint (len, &gt;=, 0);
      g_assert_cmpuint ((gsize) len, &lt;=, sizeof (data-&gt;message_buffer));
    
      handle_received_message (self, data-&gt;message_buffer, len, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Success! */
      g_task_return_boolean (task, TRUE);
    
    done:
      /* Unconditionally mark the operation as finished.
       *
       * The streams should automatically close as this
       * last reference is dropped. */
      g_clear_object (&amp;priv-&gt;connect_task);
    
      if (error != NULL)
        {
          /* Stop the operation and propagate the error. */
          g_task_return_error (task, error);
        }
    
      g_clear_object (&amp;task);
    }
    
    void
    my_object_connect_to_server_finish (MyObject      *self,
                                        GAsyncResult  *result,
                                        GError       **error)
    {
      g_return_if_fail (MY_IS_OBJECT (self));
      g_return_if_fail (g_task_is_valid (result, self));
      g_return_if_fail (error == NULL || *error == NULL);
    
      g_task_propagate_boolean (G_TASK (result), error);
    }
    
    void
    my_object_close (MyObject *self)
    {
      MyObjectPrivate *priv;
    
      g_return_if_fail (MY_IS_OBJECT (self));
    
      priv = my_object_get_instance_private (self);
    
      if (priv-&gt;connect_task != NULL)
        {
          GCancellable *cancellable = g_task_get_cancellable (priv-&gt;connect_task);
          g_cancellable_cancel (cancellable);
        }
    }
cs: 
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data);
    
    typedef struct {
      GSocketConnection *connection;  /* nullable; owned */
      guint8 message_buffer[128];
    } ConnectToServerData;
    
    static void
    connect_to_server_data_free (ConnectToServerData *data)
    {
      g_clear_object (&amp;data-&gt;connection);
    }
    
    void
    my_object_connect_to_server_async (MyObject            *self,
                                       GCancellable        *cancellable,
                                       GAsyncReadyCallback  callback,
                                       gpointer             user_data)
    {
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      ConnectToServerData *data = NULL;  /* owned */
      GFile *address_file = NULL;  /* owned */
    
      g_return_if_fail (MY_IS_OBJECT (self));
      g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
    
      priv = my_object_get_instance_private (self);
    
      if (priv-&gt;connect_task != NULL)
        {
          g_task_report_new_error (self, callback, user_data, NULL,
                                   G_IO_ERROR, G_IO_ERROR_PENDING,
                                   "Already connecting to the server.");
          return;
        }
    
      /* Nastavení, že je zrušitelné */
      if (cancellable != NULL)
        {
          g_object_ref (cancellable);
        }
      else
        {
          cancellable = g_cancellable_new ();
        }
    
      /* Nastavení úlohy */
      task = g_task_new (self, cancellable, callback, user_data);
      g_task_set_check_cancellable (task, FALSE);
    
      data = g_malloc0 (sizeof (ConnectToServerData));
      g_task_set_task_data (task, data,
                            (GDestroyNotify) connect_to_server_data_free);
    
      g_object_unref (cancellable);
    
      priv-&gt;connect_task = g_object_ref (task);
    
      /* Čtení adresy soketu */
      address_file = build_address_file ();
      g_file_load_contents_async (address_file, g_task_get_cancellable (task),
                                  connect_to_server_cb1, g_object_ref (task));
      g_object_unref (address_file);
    
      g_clear_object (&amp;task);
    }
    
    static void
    connect_to_server_cb1 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      GFile *address_file;  /* unowned */
      gchar *address = NULL;  /* owned */
      gsize address_size = 0;
      GInetAddress *inet_address = NULL;  /* owned */
      GInetSocketAddress *inet_socket_address = NULL;  /* owned */
      guint16 port = 123;
      GSocketClient *socket_client = NULL;  /* owned */
      GError *error = NULL;
    
      address_file = G_FILE (source_object);
      task = G_TASK (user_data);
      self = g_task_get_source_object (task);
      priv = my_object_get_instance_private (self);
    
      /* Dokončení načtení adresy */
      g_file_load_contents_finish (address_file, result, &amp;address,
                                   &amp;address_size, NULL, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Zpracování adresy */
      inet_address = g_inet_address_new_from_string (address);
    
      if (inet_address == NULL)
        {
          /* Chyba */
          g_set_error (&amp;error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                       "Invalid address ‘%s’.", address);
          goto done;
        }
    
      inet_socket_address = g_inet_socket_address_new (inet_address, port);
    
      /* Připojení k zadané adrese */
      socket_client = g_socket_client_new ();
    
      g_socket_client_connect_async (socket_client,
                                     G_SOCKET_CONNECTABLE (inet_socket_address),
                                     g_task_get_cancellable (task),
                                     connect_to_server_cb2,
                                     g_object_ref (task));
    
    done:
      if (error != NULL)
        {
          /* Zastavení operace a propagace chyby */
          g_clear_object (&amp;priv-&gt;connect_task);
          g_task_return_error (task, error);
        }
    
      g_free (address);
      g_clear_object (&amp;inet_address);
      g_clear_object (&amp;inet_socket_address);
      g_clear_object (&amp;socket_client);
      g_clear_object (&amp;task);
    }
    
    static void
    connect_to_server_cb2 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      ConnectToServerData *data;  /* unowned */
      GSocketClient *socket_client;  /* unowned */
      GSocketConnection *connection = NULL;  /* owned */
      GInputStream *input_stream;  /* unowned */
      GError *error = NULL;
    
      socket_client = G_SOCKET_CLIENT (source_object);
      task = G_TASK (user_data);
      data = g_task_get_task_data (task);
      self = g_task_get_source_object (task);
      priv = my_object_get_instance_private (self);
    
      /* Dokončení připojení k soketu */
      connection = g_socket_client_connect_finish (socket_client, result,
                                                   &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Uchování odkazu na připojení, takže je udržované otevřené po dobu co z něj
       * čteme: #GInputStream neudržuje odkaz na #GIOStream, který jej obsahuje */
      data-&gt;connection = g_object_ref (connection);
    
      /* Čtení zprávy z připojení. Protože je vyrovnávací paměť alokovaná jako
       * součást @data pro jednotlivé úlohy, může běžet víc úloh naráz. */
      input_stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
    
      g_input_stream_read_async (input_stream,
                                 data-&gt;message_buffer,
                                 sizeof (data-&gt;message_buffer),
                                 G_PRIORITY_DEFAULT, g_task_get_cancellable (task),
                                 connect_to_server_cb3, g_object_ref (task));
    
    done:
      if (error != NULL)
        {
          /* Zastavení operace a propagace chyby */
          g_clear_object (&amp;priv-&gt;connect_task);
          g_task_return_error (task, error);
        }
    
      g_clear_object (&amp;connection);
      g_clear_object (&amp;task);
    }
    
    static void
    connect_to_server_cb3 (GObject      *source_object,
                           GAsyncResult *result,
                           gpointer      user_data)
    {
      MyObject *self;
      MyObjectPrivate *priv;
      GTask *task = NULL;  /* owned */
      ConnectToServerData *data;  /* unowned */
      GInputStream *input_stream;  /* unowned */
      gssize len = 0;
      GError *error = NULL;
    
      input_stream = G_INPUT_STREAM (source_object);
      task = G_TASK (user_data);
      data = g_task_get_task_data (task);
      self = g_task_get_source_object (task);
      priv = my_object_get_instance_private (self);
    
      /* Dokončení čtení ze soketu */
      len = g_input_stream_read_finish (input_stream, result, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Obsluha zprávy */
      g_assert_cmpint (len, &gt;=, 0);
      g_assert_cmpuint ((gsize) len, &lt;=, sizeof (data-&gt;message_buffer));
    
      handle_received_message (self, data-&gt;message_buffer, len, &amp;error);
    
      if (error != NULL)
        {
          goto done;
        }
    
      /* Úspěch! */
      g_task_return_boolean (task, TRUE);
    
    done:
      /* Nepodmíněné označení operace za dokončenou.
       *
       * Proud dat by se měl automaticky zavřít, protože
       * je zahozen poslední odkaz. */
      g_clear_object (&amp;priv-&gt;connect_task);
    
      if (error != NULL)
        {
          /* Zastavení operace a propagace chyby */
          g_task_return_error (task, error);
        }
    
      g_clear_object (&amp;task);
    }
    
    void
    my_object_connect_to_server_finish (MyObject      *self,
                                        GAsyncResult  *result,
                                        GError       **error)
    {
      g_return_if_fail (MY_IS_OBJECT (self));
      g_return_if_fail (g_task_is_valid (result, self));
      g_return_if_fail (error == NULL || *error == NULL);
    
      g_task_propagate_boolean (G_TASK (result), error);
    }
    
    void
    my_object_close (MyObject *self)
    {
      MyObjectPrivate *priv;
    
      g_return_if_fail (MY_IS_OBJECT (self));
    
      priv = my_object_get_instance_private (self);
    
      if (priv-&gt;connect_task != NULL)
        {
          GCancellable *cancellable = g_task_get_cancellable (priv-&gt;connect_task);
          g_cancellable_cancel (cancellable);
        }
    }

note: (itstool) path: credit/name
en: The GTK+ Team
cs: Tým GTK+

note: (itstool) path: info/desc
en: Our guidelines for C code in GNOME
cs: Naše pokyny pro psaní kódu v jazyce C pro GNOME

note: (itstool) path: page/title
en: C Coding Style
cs: Styl psaní kódu v C

note: (itstool) path: page/p
en: This document presents the preferred coding style for C programs in GNOME. While coding style is very much a matter of taste, in GNOME we favor a coding style that promotes consistency, readability, and maintainability.
cs: Dokument ukazuje preferovaný styl psaní kódu pro programy v jazyce C v GNOME. Ačkoliv je styl psaní kódu hodně záležitostí osobního vkusu, v GNOME dáváme přednost stylu, který poskytne jednotnost, čitelnost a půjde dobře spravovat.

note: (itstool) path: page/p
en: We present examples of good coding style as well as examples of bad style that is not acceptable in GNOME. Please try to submit patches that conform to GNOME’s coding style; this indicates that you have done your homework to respect the project’s goal of long-term maintainability. Patches with GNOME’s coding style will also be easier to review!
cs: Ukážeme si příklady správného stylu kódu i příklady špatného stylu, který je v GNOME nepřijatelný. Snažte se prosím své příspěvky zasílat ve stylu, který GNOME vyhovuje. Dáte tím najevo, že jste svoji práci odvedli s úctou k cílům projektu, k nimž patří udržitelnost kódu. Takovéto příspěvky se také mnohem lépe kontrolují.

note: (itstool) path: note/p
en: This document is for C code. For other languages, check the <link xref="index">main page</link> of the GNOME Programming Guidelines.
cs: Tento dokument se týká kódu v jazyce C. Na další jazyky se podívejte na <link xref="index">hlavní stránku</link> pokynů k programování v GNOME.

note: (itstool) path: page/p
en: These guidelines are heavily inspired by GTK’s CODING-STYLE document, the Linux Kernel’s CodingStyle, and the GNU Coding Standards. These are slight variations of each other, with particular modifications for each project’s particular needs and culture, and GNOME’s version is no different.
cs: Tato příručka je významně inspirována dokumenty GTK’s CODING-STYLE, Linux Kernel’s CodingStyle a GNU Coding Standards. Ty se od sebe navzájem lehce odlišují konkrétními úpravami pro konkrétní potřeby projektu a jeho kulturu, a verze pro GNOME v tom není výjimkou.

note: (itstool) path: section/title
en: The Single Most Important Rule
cs: Jednoduché nejdůležitější pravidlo

note: (itstool) path: section/p
en: The single most important rule when writing code is this: <em>check the surrounding code and try to imitate it</em>.
cs: Prosté a přitom nejdůležitější pravidlo při psaní kódu je: <em>podívejte se na kód okolo a snažte se jej napodobit</em>.

note: (itstool) path: section/p
en: As a maintainer it is dismaying to receive a patch that is obviously in a different coding style to the surrounding code. This is disrespectful, like someone tromping into a spotlessly-clean house with muddy shoes.
cs: Správce bývá zděšen, když obdrží záplatu, která se vyloženě liší stylem kódování od okolního kódu. Je to bezohledné, jako když někdo vstoupí do uklizeného domu se zablácenými botami.

note: (itstool) path: section/p
en: So, whatever this document recommends, if there is already written code and you are patching it, keep its current style consistent even if it is not your favorite style.
cs: Takže to, co tento dokument doporučuje, je, abyste při psaní záplaty pro již existující kód, zachovali jeho stávající styl jednotný, i přesto že to není zrovna váš oblíbený.

note: (itstool) path: section/title
en: Line Width
cs: Šířka řádku

note: (itstool) path: section/p
en: Try to use lines of code between 80 and 120 characters long. This amount of text is easy to fit in most monitors with a decent font size. Lines longer than that become hard to read, and they mean that you should probably restructure your code. If you have too many levels of indentation, it means that you should fix your code anyway.
cs: Snažte se délku řádků v kódu udržet v rozmezí 80 až 120 znaků. Takové množství textu se vleze na většinu monitorů při použití slušné velikosti písma. Delší řádky může být obtížné číst a znamenají, že byste se měli zamyslet nad restrukturalizací svého kódu. Pokud mát příliš mnoho úrovní odsazení, rovněž to znamená, že byste měli svůj kód opravit.

note: (itstool) path: section/title
en: Indentation
cs: Odsazení

note: (itstool) path: section/p
en: In general there are two preferred indentation styles for code in GNOME.
cs: Obecně je v kódu GNOME dávána přednost dvěma stylům odsazení.

note: (itstool) path: item/p
en: Linux Kernel style. Tabs with a length of 8 characters are used for the indentation, with K&amp;R brace placement:
cs: Styl linuxového jádra. K odsazení se používají tabulátory o šířce 8 znaků a složené závorky se umisťují neodsazené (tento styl bývá označován zkratkou K&amp;R podle autorů Kernighan a Ritchie kultovní knihy The C Programming Language):

note: (itstool) path: item/p
en: GNU style. Each new level is indented by 2 spaces, braces go on a line by themselves, and they are indented as well.
cs: Styl GNU. Každá nová úroveň je odsazena 2 mezerami, složené závorky jsou samostatně na novém řádku a rovněž jsou odsazené.

note: (itstool) path: section/p
en: Both styles have their pros and cons. The most important things is to <em>be consistent</em> with the surrounding code. For example, the GTK+ library, which is GNOME’s widget toolkit, is written with the GNU style. Nautilus, GNOME’s file manager, is written in Linux kernel style. Both styles are perfectly readable and consistent when you get used to them.
cs: Oba styly mají své pro a proti. Nejdůležitější věcí ale je, aby okolní kód <em>byl jednotný</em>. Například knihovna GTK+, což je vývojářská sada pro widgety GNOME, je napsaná ve stylu GNU. Nautilus, což je správce souborů v GNOME, je napsán ve stylu linuxového jádra. Čitelné a jednotné jsou oba styly, ať použijete kterýkoliv z nich.

note: (itstool) path: section/p
en: Your first feeling when having to study or work on a piece of code that doesn’t have your preferred indentation style may be, how shall we put it, gut-wrenching. You should resist your inclination to reindent everything, or to use an inconsistent style for your patch. Remember the first rule: <em>be consistent</em> and respectful of that code’s customs, and your patches will have a much higher chance of being accepted without a lot of arguing about the right indentation style.
cs: Když musíte studovat kus cizího kódu, který nemá vámi oblíbený styl odsazování, nebo na něm dokonce pracovat, dělá se vám z toho zle. Měli byste ale překonat své touhy všchno odsazení předělat nebo použít ve své záplatě jiný styl odsazování. Pamatujte na první pravidlo: <em>dodržujte jednotnost</em> a respektujte zvyky daného kódu, a vaše záplata bude mít daleko větší šanci na přijetí, aniž byste museli vést dohady o tom, který styl odsazování je lepší.

note: (itstool) path: section/title
en: Tab Characters
cs: Znaky tabulátor

note: (itstool) path: section/p
en: <em>Do not ever change the size of tabs in your editor</em>; leave them as 8 spaces. Changing the size of tabs means that code that you didn’t write yourself will be perpetually misaligned.
cs: <em>Nikdy neměňte šířku tabulátoru ve svém editoru</em>. Ponechte ji na 8 mezerách. Pokud byste ji změnili, budete mít kód, který jste nepsali vy, věčně rozházený.

note: (itstool) path: section/p
en: Instead, set the <em>indentation size</em> as appropriate for the code you are editing. When writing in something other than Linux kernel style, you may even want to tell your editor to automatically convert all tabs to 8 spaces, so that there is no ambiguity about the intended amount of space.
cs: Místo toho si nastavte <em>šířku odsazení</em> odpovídající kódu, který upravujete. Když píšete v jiném stylu než linuxového jádra, můžete chtít říci svému editoru, aby automaticky převáděl všechny tabulátory na 8 mezer, takže nevzniknou žádné nejednoznačnosti týkající se množství mezer.

note: (itstool) path: section/title
en: Braces
cs: Závorky

note: (itstool) path: section/p
en: Curly braces should not be used for single statement blocks:
cs: Složené závorky by se neměly používat pro blok s jediným příkazem:

note: (itstool) path: section/code
en: 
    /* valid */
    if (condition)
    	single_statement ();
    else
    	another_single_statement (arg1);
cs: 
    /* dobře */
    if (condition)
    	single_statement ();
    else
    	another_single_statement (arg1);

note: (itstool) path: section/p
en: The “no block for single statements” rule has only four exceptions:
cs: Z tohoto pravidla existují čtyři výjimky:

note: (itstool) path: item/p
en: In GNU style, if either side of an if-else statement has braces, both sides should, to match up indentation:
cs: Ve stylu GNU, když má jedna část výrazu if-else závorky, měly by je mít obě, aby měly i stejné odsazení:

note: (itstool) path: item/code
en: 
    /* valid GNU style */
    if (condition)
      {
        foo ();
        bar ();
      }
    else
      {
        baz ();
      }
cs: 
    /* platný styl GNU */
    if (condition)
      {
        foo ();
        bar ();
      }
    else
      {
        baz ();
      }

note: (itstool) path: item/code
en: 
    /* invalid */
    if (condition)
      {
        foo ();
        bar ();
      }
    else
      baz ();
cs: 
    /* špatně */
    if (condition)
      {
        foo ();
        bar ();
      }
    else
      baz ();

note: (itstool) path: item/p
en: If the single statement covers multiple lines, e.g. for functions with many arguments, and it is followed by <code>else</code> or <code>else if</code>:
cs: Samostatný výraz roztažený přes více řádků, např. funkce s hodně argumenty, a následovaný <code>else</code> nebo <code>else if</code>:

note: (itstool) path: item/code
en: 
    /* valid Linux kernel style */
    if (condition) {
    	a_single_statement_with_many_arguments (some_lengthy_argument,
    						another_lengthy_argument,
    						and_another_one,
    						plus_one);
    } else
    	another_single_statement (arg1, arg2);
    
    /* valid GNU style */
    if (condition)
      {
        a_single_statement_with_many_arguments (some_lengthy_argument,
                                                another_lengthy_argument,
                                                and_another_one,
                                                plus_one);
      }
    else
      {
        another_single_statement (arg1, arg2);
      }
cs: 
    /* platný styl linuxového jádra */
    if (condition) {
    	a_single_statement_with_many_arguments (some_lengthy_argument,
    						another_lengthy_argument,
    						and_another_one,
    						plus_one);
    } else
    	another_single_statement (arg1, arg2);
    
    /* platný styl GNU */
    if (condition)
      {
        a_single_statement_with_many_arguments (some_lengthy_argument,
                                                another_lengthy_argument,
                                                and_another_one,
                                                plus_one);
      }
    else
      {
        another_single_statement (arg1, arg2);
      }

note: (itstool) path: item/p
en: If the condition is composed of many lines:
cs: Když je podmínka rozdělená na více řádků:

note: (itstool) path: item/code
en: 
    /* valid Linux kernel style */
    if (condition1 ||
        (condition2 &amp;&amp; condition3) ||
        condition4 ||
        (condition5 &amp;&amp; (condition6 || condition7))) {
    	a_single_statement ();
    }
    
    /* valid GNU style */
    if (condition1 ||
        (condition2 &amp;&amp; condition3) ||
        condition4 ||
        (condition5 &amp;&amp; (condition6 || condition7)))
      {
        a_single_statement ();
      }
cs: 
    /* platný styl linuxového jádra */
    if (condition1 ||
        (condition2 &amp;&amp; condition3) ||
        condition4 ||
        (condition5 &amp;&amp; (condition6 || condition7))) {
    	a_single_statement ();
    }
    
    /* platný styl GNU */
    if (condition1 ||
        (condition2 &amp;&amp; condition3) ||
        condition4 ||
        (condition5 &amp;&amp; (condition6 || condition7)))
      {
        a_single_statement ();
      }

note: (itstool) path: item/p
en: Note that such long conditions are usually hard to understand. A good practice is to set the condition to a boolean variable, with a good name for that variable. Another way is to move the long condition to a function.
cs: Uvědomte si ale, že takovéto dlouhé podmínky jsou náročné na porozumění. Proto je dobrým zvykem nastavit jednotlivé části podmínky do pravdivostních proměnných s popisnými názvy. Jinou možností je přesunout dlouhou podmínku do funkce.

note: (itstool) path: item/p
en: Nested <code>if</code>s, in which case the block should be placed on the outermost <code>if</code>:
cs: Vnořené <code>if</code> v případě, že má být blok umístěn v nadřazeném <code>if</code>:

note: (itstool) path: item/code
en: 
    /* valid Linux kernel style */
    if (condition) {
    	if (another_condition)
    		single_statement ();
    	else
    		another_single_statement ();
    }
    
    /* valid GNU style */
    if (condition)
      {
        if (another_condition)
          single_statement ();
        else
          another_single_statement ();
      }
cs: 
    /* platný styl linuxového jádra */
    if (condition) {
    	if (another_condition)
    		single_statement ();
    	else
    		another_single_statement ();
    }
    
    /* platný styl GNU */
    if (condition)
      {
        if (another_condition)
          single_statement ();
        else
          another_single_statement ();
      }

note: (itstool) path: item/code
en: 
    /* invalid */
    if (condition)
    	if (another_condition)
    		single_statement ();
    	else if (yet_another_condition)
    		another_single_statement ();
cs: 
    /* špatně */
    if (condition)
    	if (another_condition)
    		single_statement ();
    	else if (yet_another_condition)
    		another_single_statement ();

note: (itstool) path: section/p
en: In general, new blocks should be placed on a new indentation level, like this:
cs: Obecně by nový blok měl být umístěn v nové úrovni odsazení, nějak takto:

note: (itstool) path: section/p
en: While curly braces for function definitions should rest on a new line they should not add an indentation level:
cs: I když mají být složené závorky pro definici funkce na novém řádku, neměly by být odsazené:

note: (itstool) path: section/code
en: 
    /* valid Linux kernel style*/
    static void
    my_function (int argument)
    {
    	do_my_things ();
    }
    
    /* valid GNU style*/
    static void
    my_function (int argument)
    {
      do_my_things ();
    }
cs: 
    /* platný styl linuxového jádra*/
    static void
    my_function (int argument)
    {
    	do_my_things ();
    }
    
    /* platný styl GNU */
    static void
    my_function (int argument)
    {
      do_my_things ();
    }

note: (itstool) path: section/code
en: 
    /* invalid */
    static void
    my_function (int argument) {
    	do_my_things ();
    }
    
    /* invalid */
    static void
    my_function (int argument)
      {
        do_my_things ();
      }
cs: 
    /* špatně */
    static void
    my_function (int argument) {
    	do_my_things ();
    }
    
    /* špatně */
    static void
    my_function (int argument)
      {
        do_my_things ();
      }

note: (itstool) path: section/title
en: Conditions
cs: Podmínky

note: (itstool) path: section/p
en: Do not check boolean values for equality. By using implicit comparisons, the resulting code can be read more like conversational English. Another rationale is that a ‘true’ value may not be necessarily equal to whatever the <code>TRUE</code> macro uses. For example:
cs: U pravdivostních hodnot neprovádějte kontrolu na rovnost. Když ponecháte výchozí porovnání, bude výsledný kód čitelnější jakoby přirozená angličtina. Dalším logickým důvodem je, že skutečná hodnota „pravda“ nemusí nutně být totéž, co použití makra <code>TRUE</code>. Například:

note: (itstool) path: section/code
en: 
    /* invalid */
    if (found == TRUE)
    	do_foo ();
    
    /* invalid */
    if (found == FALSE)
    	do_bar ();
cs: 
    /* špatně */
    if (found == TRUE)
    	do_foo ();
    
    /* špatně */
    if (found == FALSE)
    	do_bar ();

note: (itstool) path: section/code
en: 
    /* valid */
    if (found)
    	do_foo ();
    
    /* valid */
    if (!found)
    	do_bar ();
cs: 
    /* dobře */
    if (found)
    	do_foo ();
    
    /* dobře */
    if (!found)
    	do_bar ();

note: (itstool) path: section/p
en: The C language uses the value 0 for many purposes. As a numeric value, the end of a string, a null pointer and the <code>FALSE</code> boolean. To make the code clearer, you should write code that highlights the specific way 0 is used. So when reading a comparison, it is possible to know the variable type. For boolean variables, an implicit comparison is appropriate because it’s already a logical expression. Other variable types are not logical expressions by themselves, so an explicit comparison is better:
cs: Jazyk C používá hodnotu 0 k mnoha účelům. Jako číselnou hodnotu, zakončení řetězce, prázdný ukazatel a pravdivostní hodnotu <code>FALSE</code>. Aby byl kód lépe čitelný, měli byste jej psát tak, aby byl konkrétní význam 0 zdůrazněn. Proto je při porovnávání dobré vědět, o jaký typ proměnné se jedná. U pravdivostních proměnných je výchozí porovnání v pořádku, protože se jedná o logický výraz. U ostatních typů samotných o logický výraz nejde, takže výslovné porovnání je lepší:

note: (itstool) path: section/code
en: 
    /* valid */
    if (some_pointer == NULL)
    	do_blah ();
    
    /* valid */
    if (number == 0)
    	do_foo ();
    
    /* valid */
    if (str != NULL &amp;&amp; *str != '\0')
    	do_bar ();
cs: 
    /* dobře */
    if (some_pointer == NULL)
    	do_blah ();
    
    /* dobře */
    if (number == 0)
    	do_foo ();
    
    /* dobře */
    if (str != NULL &amp;&amp; *str != '\0')
    	do_bar ();

note: (itstool) path: section/code
en: 
    /* invalid */
    if (!some_pointer)
    	do_blah ();
    
    /* invalid */
    if (!number)
    	do_foo ();
    
    /* invalid */
    if (str &amp;&amp; *str)
    	do_bar ();
cs: 
    /* špatně */
    if (!some_pointer)
    	do_blah ();
    
    /* špatně */
    if (!number)
    	do_foo ();
    
    /* špatně */
    if (str &amp;&amp; *str)
    	do_bar ();

note: (itstool) path: section/title
en: Functions
cs: Funkce

note: (itstool) path: section/p
en: Functions should be declared by placing the returned value on a separate line from the function name:
cs: Funkce by měly být deklarovány s návratovou hodnotou umístěnou na zvláštní řádek před názvem funkce:

note: (itstool) path: section/p
en: The argument list must be broken into a new line for each argument, with the argument names right aligned, taking into account pointers:
cs: Seznam argumentů musí být rozdělen na jednotlivé řádky pro každý z argumentů a názvy argumentů jsou správně zarovnané, přičemž se berou do úvahy ukazatele:

note: (itstool) path: section/p
en: If you use Emacs, you can use <code>M-x align</code> to do this kind of alignment automatically. Just put the point and mark around the function’s prototype, and invoke that command.
cs: Pokud používáte Emacs, můžete vyžít <code>M-x align</code> k automatickému zarovnání tohoto typu. Stačí vložit okolo prototypu funkce bod a značku a vyvolat tento příkaz.

note: (itstool) path: section/p
en: The alignment also holds when invoking a function without breaking the line length limit:
cs: Zarovnání se dodržuje i při vyvolání funkce, která neporušuje omezení délky řádku:

note: (itstool) path: section/title
en: Whitespace
cs: Bílé znaky

note: (itstool) path: section/p
en: Always put a space before an opening parenthesis but never after:
cs: Vždy dejte mezeru před otevírací závorku, ale nikdy ne za ni:

note: (itstool) path: section/code
en: 
    /* valid */
    if (condition)
    	do_my_things ();
    
    /* valid */
    switch (condition) {
    }
cs: 
    /* dobře */
    if (condition)
    	do_my_things ();
    
    /* dobře */
    switch (condition) {
    }

note: (itstool) path: section/code
en: 
    /* invalid */
    if(condition)
    	do_my_things();
    
    /* invalid */
    if ( condition )
    	do_my_things ( );
cs: 
    /* špatně */
    if(condition)
    	do_my_things();
    
    /* špatně */
    if ( condition )
    	do_my_things ( );

note: (itstool) path: section/p
en: When declaring a structure type use newlines to separate logical sections of the structure:
cs: Při deklaraci struktury oddělte její logické části pomocí prázdného řádku:

note: (itstool) path: section/p
en: Do not eliminate whitespace and newlines just because something would fit on a single line:
cs: Neodstraňujte bílé znaky a zalomení jen proto, že by se něco vlezlo na jeden řádek:

note: (itstool) path: section/code
en: 
    /* invalid */
    if (condition) foo (); else bar ();
cs: 
    /* špatně */
    if (condition) foo (); else bar ();

note: (itstool) path: section/p
en: Do eliminate trailing whitespace on any line, preferably as a separate patch or commit. Never use empty lines at the beginning or at the end of a file.
cs: Odstraňte bílé znaky na koncích řádků, hlavně u samostatných záplat nebo zařazení. Nikdy nepoužívejte prázdné řádky na začátku nebo na konci souboru.

note: (itstool) path: section/p
en: This is a little Emacs function that you can use to clean up lines with trailing whitespace:
cs: Zde je drobná funkce pro Emacs, kterou můžete použít k vyčištění bílých znaků na koncích řádků:

note: (itstool) path: section/title
en: The <code>switch</code> Statement
cs: Výraz <code>switch</code>

note: (itstool) path: section/p
en: A <code>switch</code> should open a block on a new indentation level, and each <code>case</code> should start on the same indentation level as the curly braces, with the case block on a new indentation level:
cs: Příkaz <code>switch</code> by měl otevírat blok na nové úrovni odsazení a každý <code>case</code> by měl začínat na stejné úrovni, jako složené závorky, s příslušným blokem na nové úrovni odsazení:

note: (itstool) path: section/code
en: 
    /* valid Linux kernel style */
    switch (condition) {
    case FOO:
    	do_foo ();
    	break;
    
    case BAR:
    	do_bar ();
    	break;
    }
    
    /* valid GNU style */
    switch (condition)
      {
      case FOO:
        do_foo ();
        break;
    
      case BAR:
        do_bar ();
        break;
      }
cs: 
    /* platný styl linuxového jádra */
    switch (condition) {
    case FOO:
    	do_foo ();
    	break;
    
    case BAR:
    	do_bar ();
    	break;
    }
    
    /* platný styl GNU */
    switch (condition)
      {
      case FOO:
        do_foo ();
        break;
    
      case BAR:
        do_bar ();
        break;
      }

note: (itstool) path: section/code
en: 
    /* invalid */
    switch (condition) {
      case FOO: do_foo (); break;
      case BAR: do_bar (); break;
    }
    
    /* invalid */
    switch (condition)
      {
      case FOO: do_foo ();
        break;
      case BAR: do_bar ();
        break;
      }
    
    /* invalid */
    switch (condition)
      {
        case FOO:
        do_foo ();
        break;
        case BAR:
        do_bar ();
        break;
      }
cs: 
    /* špatně */
    switch (condition) {
      case FOO: do_foo (); break;
      case BAR: do_bar (); break;
    }
    
    /* špatně */
    switch (condition)
      {
      case FOO: do_foo ();
        break;
      case BAR: do_bar ();
        break;
      }
    
    /* špatně */
    switch (condition)
      {
        case FOO:
        do_foo ();
        break;
        case BAR:
        do_bar ();
        break;
      }

note: (itstool) path: section/p
en: It is preferable, though not mandatory, to separate the various cases with a newline:
cs: Preferované, ale ne povinné, je oddělení různých případů prázdným řádkem:

note: (itstool) path: section/p
en: The <code>break</code> statement for the <code>default</code> case is not mandatory.
cs: Výraz <code>break</code> pro případ <code>default</code> není povinný.

note: (itstool) path: section/p
en: If switching over an enumerated type, a <code>case</code> statement must exist for every member of the enumerated type. For members you do not want to handle, alias their <code>case</code> statements to <code>default</code>:
cs: Pokud přepínáte podle výčtového typu, musí být výraz <code>case</code> uveden pro všechny hodnoty daného výčtu. Hodnoty, které není potřeba obsloužit, uveďte dohromady s případem <code>default</code>:

note: (itstool) path: section/p
en: If most members of the enumerated type should not be handled, consider using an <code>if</code> statement instead of a <code>switch</code>.
cs: Pokud není potřeba obsloužit většinu z hodnot výčtu, měli byste pouvažovat spíš o výrazu <code>if</code> namísto <code>switch</code>.

note: (itstool) path: section/p
en: If a <code>case</code> block needs to declare new variables, the same rules as the inner blocks apply (see above); the <code>break</code> statement should be placed outside of the inner block:
cs: Když blok <code>case</code> potřebuje deklarovat nové proměnné, použije se stejné pravidlo jako pro vnitřní blok (viz výše). Příkaz <code>break</code> by měl být umístěn mimo vnitřní blok:

note: (itstool) path: section/code
en: 
    /* valid GNU style */
    switch (condition)
      {
      case FOO:
        {
          int foo;
    
          foo = do_foo ();
        }
        break;
    
      …
      }
cs: 
    /* platný styl GNU */
    switch (condition)
      {
      case FOO:
        {
          int foo;
    
          foo = do_foo ();
        }
        break;
    
      …
      }

note: (itstool) path: section/title
en: Header Files
cs: Hlavičkové soubory

note: (itstool) path: section/p
en: The only major rule for headers is that the function definitions should be vertically aligned in three columns:
cs: Jediné hlavní pravidlo pro hlavičkové soubory je, že definici funkcí by měly být svisle zarovnané do tří sloupců:

note: (itstool) path: section/p
en: The maximum width of each column is given by the longest element in the column:
cs: Maximální šířka jednotlivých sloupců je určena nejdelším prvkem ve sloupci:

note: (itstool) path: section/p
en: It is also possible to align the columns to the next tab:
cs: Sloupce je možné zarovnávat také na nejbližší tabulátor:

note: (itstool) path: section/p
en: As before, you can use <code>M-x align</code> in Emacs to do this automatically.
cs: Jak již bylo uvedeno dříve, můžete v editoru Emacs použít <code>M-x align</code>, aby se to provedlo automaticky.

note: (itstool) path: section/p
en: If you are creating a public library, try to export a single public header file that in turn includes all the smaller header files into it. This is so that public headers are never included directly; rather a single include is used in applications. For example, GTK+ uses the following in its header files that should not be included directly by applications:
cs: Když vytváříte veřejnou knihovnu, zkuste exportovat jediný veřejný hlavičkový soubor, ve kterém budou pomocí include vložené všechny menší hlavičkové soubory. Je to proto, aby veřejné hlavičky nikdy nebyly vložené přímo. Místo toho se v aplikacích použije jediná direktiva include. Například GTK+ ve svých hlavičkových souborech, který by neměl být aplikací vloženy přímo, používá následující:

note: (itstool) path: section/p
en: For libraries, all headers should have inclusion guards (for internal usage) and C++ guards. These provide the <code>extern "C"</code> magic that C++ requires to include plain C headers:
cs: U knihoven by všechny hlavičkové soubory měly mít ochranu proti vícenásobnému vložení (pro interní použití) a pro integraci s C++. Ta poskytuje magické <code>extern "C"</code>, které vyžaduje C++ při vložení hlavičkového souboru prostého C:

note: (itstool) path: section/title
en: GObject Classes
cs: Třídy GObject

note: (itstool) path: section/p
en: GObject class definitions and implementations require some additional coding style notices, and should always be <link xref="namespacing#gobject">correctly namespaced</link>.
cs: Definice a implementace třídy GObject vyžadují pár doplňujících poznámek ke stylu kódování a vždy by měly mít uveden <link xref="namespacing#gobject">správný jmenný prostor</link>.

note: (itstool) path: section/p
en: Typedef declarations should be placed at the beginning of the file:
cs: Deklarace typedef by měly být umístěny na začátku souboru:

note: (itstool) path: section/p
en: This includes enumeration types:
cs: Včetně výčtových typů:

note: (itstool) path: section/p
en: And callback types:
cs: A typů zpětných volání:

note: (itstool) path: section/p
en: Instance structures should be declared using <code>G_DECLARE_FINAL_TYPE</code> or <code>G_DECLARE_DERIVABLE_TYPE</code>:
cs: Struktury instance by měly být deklarovány pomocí <code>G_DECLARE_FINAL_TYPE</code> nebo <code>G_DECLARE_DERIVABLE_TYPE</code>:

note: (itstool) path: section/p
en: For final types, private data can be stored in the object struct, which should be defined in the C file:
cs: Pro konečné typy mohou být privátní data uchována ve struktuře, která by měla být definována v souboru C:

note: (itstool) path: section/p
en: For derivable types, private data must be stored in a private struct in the C file, configured using <code>G_DEFINE_TYPE_WITH_PRIVATE()</code> and accessed using a <code>_get_instance_private()</code> function:
cs: Pro typy, z který lze odvozovat další typy, musí být privátní data uchována v privátní struktuře v souboru C, která je nastavena pomocí <code>G_DEFINE_TYPE_WITH_PRIVATE()</code> a dostanete se k ní pomocí funkce <code>_get_instance_private()</code>:

note: (itstool) path: section/p
en: Always use the <code>G_DEFINE_TYPE()</code>, <code>G_DEFINE_TYPE_WITH_PRIVATE()</code>, and <code>G_DEFINE_TYPE_WITH_CODE()</code> macros, or their abstract variants <code>G_DEFINE_ABSTRACT_TYPE()</code>, <code>G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE()</code>, and <code>G_DEFINE_ABSTRACT_TYPE_WITH_CODE()</code>; also, use the similar macros for defining interfaces and boxed types.
cs: Vždy používejte makra <code>G_DEFINE_TYPE()</code>, <code>G_DEFINE_TYPE_WITH_PRIVATE()</code> a <code>G_DEFINE_TYPE_WITH_CODE()</code> nebo jejich abstraktní varianty <code>G_DEFINE_ABSTRACT_TYPE()</code>, <code>G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE()</code> a <code>G_DEFINE_ABSTRACT_TYPE_WITH_CODE()</code>. Podobná makra používejte také pro definování rozhraní a boxované typy.

note: (itstool) path: section/p
en: Interface types should always have the dummy typedef for cast purposes:
cs: Mezi typy rozhraní by vždy měla být i vzorová definice typu pro účely přetypování:

note: (itstool) path: section/p
en: The interface structure should have ‘Interface’ postfixed to the dummy typedef:
cs: Struktura rozhraní by měla mít v definici typu k názvu přidáno „Interface“:

note: (itstool) path: section/p
en: Interfaces must have the following macros:
cs: Rozhraní musí mít následující makra:

note: (itstool) path: td/p
en: Macro
cs: Makro

note: (itstool) path: td/p
en: Expands to
cs: Rozbalí se na

note: (itstool) path: section/title
en: Memory Allocation
cs: Přidělování paměti

note: (itstool) path: section/p
en: When dynamically allocating data on the heap use <code>g_new()</code>.
cs: Když dynamicky alokujete data na haldě, použijte <code>g_new()</code>.

note: (itstool) path: section/p
en: Public structure types should always be returned after being zero-ed, either explicitly for each member, or by using <code>g_new0()</code>.
cs: Veřejné typy struktur by měly být vraceny vždy vynulované, buď výslovně pro jednotlivé členy struktury nebo pomocí <code>g_new0()</code>.

note: (itstool) path: section/p
en: See <link xref="memory-management"/> for more details.
cs: Další podrobnosti viz <link xref="memory-management"/>.

note: (itstool) path: section/title
en: Macros
cs: Makra

note: (itstool) path: section/p
en: Try to avoid private macros unless strictly necessary. Remember to <code>#undef</code> them at the end of a block or a series of functions needing them.
cs: Snažte se vyhnout privátním makrům, pokud nejsou vysloveně nutná. Pamatujte na jejich zrušení pomocí <code>#undef</code> na konci bloku nebo funkce nebo série funkcí, které je potřebovali.

note: (itstool) path: section/p
en: Inline functions are usually preferable to private macros.
cs: Před makry je obvykle dávána přednost vloženým funkcím.

note: (itstool) path: section/p
en: Public macros should not be used unless they evaluate to a constant.
cs: Veřejná makra by se neměla používat, pokud nejsou vyhodnocována do konstanty.

note: (itstool) path: section/title
en: Public API
cs: Veřejné API

note: (itstool) path: section/p
en: Avoid exporting variables as public API, since this is cumbersome on some platforms. It is always preferable to add getters and setters instead. Also, beware global variables in general.
cs: Vyhněte se exportování proměnných jako veřejné API, protože na některých platformách to může být nevhodné. Vždy místo toho dejte přednost funkcím pro získání a nastavení hodnoty. Zkuste se také vyhnout globálním proměnným.

note: (itstool) path: section/title
en: Private API
cs: Privátní API

note: (itstool) path: section/p
en: Non-exported functions that are needed in more than one source file should be prefixed with an underscore (‘_’), and declared in a private header file. For example, <code>_mylib_internal_foo()</code>.
cs: Neexportované funkce, které jsou zapotřebí ve více než jednom zdrojovém souboru by měly mít prefix v podobě podtržítka („_“) a měly by být deklarovány v privátním hlavičkovém souboru. Například <code>_mylib_internal_foo()</code>.

note: (itstool) path: section/p
en: Underscore-prefixed functions are never exported.
cs: Funkce začínající podtržítkem nejsou nikdy exportovány.

note: (itstool) path: section/p
en: Non-exported functions that are only needed in one source file should be declared static.
cs: Neexportované funkce, které jsou zapotřebí jen v jednom zdrojovém souboru by měly být deklarované jako statické.

note: (itstool) path: license/p
en: This work is licensed under a <_:link-1/>.
cs: Toto dílo je licencováno pod <_:link-1/>.

note: (itstool) path: license/p
en: As a special exception, the copyright holders give you permission to copy, modify, and distribute the example code contained in this document under the terms of your choosing, without restriction.
cs: Jako zvláštní výjimka se vám držitelem autorských práv uděluje svolení kopírovat, upravovat a šířit ukázkový kód obsažený v tomto dokumentu za podmínek, které si zvolíte, bez dalších omezení.

note: (itstool) path: info/desc
en: Simple persistent object stores
cs: Úložiště pro jednoduché trvalé objekty

note: (itstool) path: page/title
en: Databases
cs: Databáze

note: (itstool) path: item/p
en: Use databases for appropriate use cases: not configuration data (use GSettings). (<link xref="#when-to-use-databases"/>)
cs: Databáze používejte ve vhodných případech, tzn. ne pro nastavení (k tomu slouží GSettings). (<link xref="#when-to-use-databases"/>)

note: (itstool) path: item/p
en: Choose between GOM and GVDB based on whether indexing is required. (<link xref="#when-to-use-databases"/>)
cs: Volte mezi GOM a GVDB podle toho, jestli je zapotřebí indexování. (<link xref="#when-to-use-databases"/>)

note: (itstool) path: item/p
en: Consider your vacuuming policy before committing to using GOM. (<link xref="#when-to-use-databases"/>)
cs: Popřemýšlejte o zásadách úklidu databáze, než zařadíte používání GOM. (<link xref="#when-to-use-databases"/>)

note: (itstool) path: item/p
en: Avoid SQL injection vulnerabilities by using prepared statements. (<link xref="#sql-injection"/>)
cs: Zranitelnosti v podobě injektáže SQL se vyhněte pomocí předpřipravených dotazů. (<link xref="#sql-injection"/>)

note: (itstool) path: section/title
en: When to Use Databases
cs: Kdy používat databáze

note: (itstool) path: section/p
en: Configuration data should be stored in <link href="https://developer.gnome.org/gio/stable/GSettings.html">GSettings</link>. As a rule of thumb, if some data needs to be persistent and affects how an application behaves, it is configuration data. If it could potentially be subject to policies imposed by the system administrator (such as proxy or lockdown settings), it is configuration data. If it contains user created content, it is not configuration data, and should not be stored in GSettings.
cs: Data nastavení by měla být uložena v <link href="https://developer.gnome.org/gio/stable/GSettings.html">GSettings</link>. Platí, že data, která musí být trvalá a ovlivňují chování aplikace, jsou data nastavení. Pokud se jedná o záležitost, na kterou se vztahují zásady určené správcem systému (jako třeba nastavení proxy nebo zamykání), jde o data nastavení. Jestliže to ale obsahuje uživatelem vytvořený obsah, nejedná se o data nastavení a nemělo by to být uloženo v GSettings.

note: (itstool) path: section/p
en: For such situations where user data is highly structured, storing it in a database is sensible. There are two main databases suggested for use within GNOME: GOM and GVDB. GOM is a wrapper around SQLite, and hence implements indexing of fields and SQL-style queries. GVDB is a much simpler object store, supporting fast serialization of a dictionary of objects to disk.
cs: Pro situace, kdy jsou data vysoce strukturovaná, je pro uchování rozumným řešením databáze. V GNOME jsou doporučovány dvě hlavní databáze: GOM a GVDB. GOM ve skutečnosti obaluje SQLite a tudíž implementuje indexaci polí a dotazy ve stylu SQL. GVDB je mnohem jednodušší úložiště objektů, které podporuje rychlou serializaci slovníku objektů na disk.

note: (itstool) path: section/p
en: GOM should be used if you need advanced features, especially indexing. GVDB should be used otherwise.
cs: GOM by s měl použít, když jsou zapotřebí pokročilé funkce, především indexování. V ostatních případech by mělo být použito GVDB.

note: (itstool) path: section/p
en: Before deciding to use GOM (and hence SQLite), you must consider a vacuuming policy for the database, and whether your use case will interact well with SQLite’s vacuuming system. Vacuuming is effectively SQLite’s term for defragmenting the database — if a database is not vacuumed appropriately, performance will degrade and the database size will increase indefinitely. Read <link href="http://blogs.gnome.org/jnelson/2015/01/06/sqlite-vacuum-and-auto_vacuum/">this article</link> on vacuuming for more information; please consider it before choosing to use GOM.
cs: Dříve, než se rozhodnete použít GOM (a tím pádem SQLite), musíte zvážit zásady úklidu databáze (vacuum) a jestli vaše použití bude dobře spolupracovat s úklidovým systémem SQLite. Úklid je v podstatě výraz používaný u SQLite (respektive u databází obecně) pro defragmentaci databáze — pokud databáze není řádně defragmentovaná, degraduje to výkon a značně narůstá její velikost. Více informací se dočtete v <link href="http://blogs.gnome.org/jnelson/2015/01/06/sqlite-vacuum-and-auto_vacuum/">tomto článku</link> na dané téma. Popřemýšlejte o něm, než zvolíte použití GOM.

note: (itstool) path: section/p
en: GNOME has another database library: GNOME Data Access (GDA). This is targeted at abstracting access to various types of relational database, for use in a database utility program or office program, for example. It is not suitable for storing <link href="https://developer.gnome.org/gio/stable/GSettings.html">user settings</link>.
cs: GNOME má ještě další databázovou knihovnu: GNOME Data Access (GDA). Je zaměřená na abstraktní přístup k různým typům relačních databází, pro použití například v programech pro administrační práci s databázemi nebo v kancelářských programech. Naopak není vhodná pro ukládání <link href="https://developer.gnome.org/gio/stable/GSettings.html">uživatelských nastavení</link>.

note: (itstool) path: section/title
en: Using GOM
cs: Používání GOM

note: (itstool) path: section/p
en: Providing a GOM tutorial is beyond the scope of this document, but a <link href="https://developer.gnome.org/gom/">reference manual is available</link>.
cs: Výuka použití GOM přesahuje rámec tohoto dokumentu, ale <link href="https://developer.gnome.org/gom/">je k dispozici referenční příručka</link>.

note: (itstool) path: section/title
en: SQL Injection
cs: Injektáž SQL

note: (itstool) path: section/p
en: GOM does allow access to the lower level SQLite query APIs. When using them, queries <em style="strong">must</em> be constructed using SQLite’s <link href="https://www.sqlite.org/c3ref/stmt.html">prepared statement</link> and <link href="https://www.sqlite.org/c3ref/bind_blob.html">value binding</link> API, rather than by constructing SQL strings then passing them to SQLite to parse. Constructing strings makes <link href="https://en.wikipedia.org/wiki/SQL_injection">SQL injection</link> vulnerabilities very likely, which can give attackers access to arbitrary user data from the database.
cs: GOM neumožňuje přístup k nízkoúrovňovému dotazovacímu API databáze SQLite. Když jej používáte, <em style="strong">musíte</em> místo přímého sestavení řetězce s SQL, a jeho následného předání ke zpracování, dotazy sestavovat pomocí <link href="https://www.sqlite.org/c3ref/stmt.html">předpřipravených výrazů</link> SQLite a API pro <link href="https://www.sqlite.org/c3ref/bind_blob.html">napojení hodnot</link>. Přímé sestavování řetězců zvyšuje pravděpodobnost útoků typu <link href="https://cs.wikipedia.org/wiki/SQL_injection">injektování SQL</link>, pomocí kterých může útočník získat přístup k libovolným uživatelským datům v databázi.

note: (itstool) path: section/title
en: Using GVDB
cs: Používání GVDB

note: (itstool) path: section/p
en: GVDB has a simple API which mirrors a conventional hash table. Presently, GVDB is only available as a copy-and-paste library; fetch the most recent copy of the code from <link href="https://gitlab.gnome.org/GNOME/gvdb">GVDB git</link> and copy it into your project. It is licensed under LGPLv2.1+.
cs: GVDB má jednoduché API, které zrcadlí běžné hašovací tabulky. V současnosti je GVDB odstupné jen jako knihovna pro postup „kopírovat a vložit“. Stáhněte si nejnovější kopii kódu z <link href="https://gitlab.gnome.org/GNOME/gvdb">gitu GVDB</link> a nakopírujte ji do svého projektu. Je licencována pod LGPLv2.1+.

note: (itstool) path: section/p
en: A full GVDB tutorial is beyond the scope of this document.
cs: Úplná výuka GVDB překračuje rozsah tohoto dokumentu.

note: (itstool) path: info/desc
en: Adding documentation to libraries and APIs
cs: Doplnění dokumentace ke knihovnám a k API

note: (itstool) path: page/title (itstool) path: section/title
en: Documentation
cs: Dokumentace

note: (itstool) path: item/p
en: Use gtk-doc with up-to-date settings for API documentation. (<link xref="#gtk-doc"/>)
cs: Pro dokumentaci API používejte gtk-doc s nastavením pro udržování aktuální podoby. (<link xref="#gtk-doc"/>)

note: (itstool) path: item/p
en: Use XML entities for including external symbols into the documentation. (<link xref="#build-system"/>)
cs: Používejte prvky XML pro zahrnutí externích symbolů do dokumentace. (<link xref="#build-system"/>)

note: (itstool) path: item/p
en: Use a consistent, standard, table of contents for all API documentation to maintain familiarity. (<link xref="#standard-layout"/>)
cs: Používejte jednotný standardní obsah ve všech dokumentacích k API, aby šla udržovat podle běžných zvyklostí. (<link xref="#standard-layout"/>)

note: (itstool) path: item/p
en: Use <cmd>gdbus-codegen</cmd> to generate D-Bus API documentation to include in the gtk-doc build. (<link xref="#dbus-api"/>)
cs: Používejte <cmd>gdbus-codegen</cmd> k vygenerování dokumentace k API pro D-Bus, která se zahrne do sestavení gtk-doc. (<link xref="#dbus-api"/>)

note: (itstool) path: item/p
en: Add introspection annotations to all API documentation. (<link xref="#introspection-annotations"/>)
cs: Do veškeré dokumentace k API přidejte anotace k introspekci. (<link xref="#introspection-annotations"/>)

note: (itstool) path: item/p
en: Add <code>Since</code> lines to all API documentation. (<link xref="#symbol-versioning"/>)
cs: Do všech dokumentací k API doplňte řádky <code>Since</code>. (<link xref="#symbol-versioning"/>)

note: (itstool) path: item/p
en: Enable gtk-doc tests. (<link xref="#keeping-up-to-date"/>)
cs: Povolte testy gtk-doc. (<link xref="#keeping-up-to-date"/>)

note: (itstool) path: section/p
en: The preferred documentation system for GNOME libraries is <link href="http://www.gtk.org/gtk-doc/">gtk-doc</link>, which extracts inline comments from the code to let you build a <link href="http://docbook.org/">DocBook</link> document and collection of HTML pages. These can then be read in <link href="https://wiki.gnome.org/Apps/Devhelp">Devhelp</link>. A lot of GNOME’s infrastructure is built to handle with documentation written using gtk-doc.
cs: Upřednostňovaným systémem pro dokumentovaní knihoven GNOME je <link href="http://www.gtk.org/gtk-doc/">gtk-doc</link>, který získává vložené komentáře z kódu, aby z nich sestavil dokument <link href="http://docbook.org/">DocBook</link> a sadu stránek HTML. Ty je pak možné číst v aplikaci <link href="https://wiki.gnome.org/Apps/Devhelp">Devhelp</link>. Velká část infrastruktury GNOME je postavena tak, aby pracoval s dokumentací napsanou pomocí gtk-doc.

note: (itstool) path: section/title
en: Build System
cs: Systém sestavení

note: (itstool) path: section/p
en: To integrate gtk-doc into a project’s build system, follow the <link href="https://developer.gnome.org/gtk-doc-manual/stable/settingup.html.en"> instructions in the gtk-doc manual</link>. Note that while the <file>sections.txt</file> file is automatically generated the first time gtk-doc is run, it is not generated subsequently, and should be kept up to date manually. It should also be <link href="https://developer.gnome.org/gtk-doc-manual/stable/settingup_vcs.html.en"> in version control</link>.
cs: Při začleňování gtk-doc do systému sestavení u projektu <link href="https://developer.gnome.org/gtk-doc-manual/stable/settingup.html.en">se řiďte instrukcemi v příručce k gtk-doc</link>. Přípomínáme, že soubor <file>sections.txt</file> je sice vygenerován automaticky, ale jen při prvním spuštění gtk-doc. Následně již generován není a musí být udržován ručně. Proto by měl být také <link href="https://developer.gnome.org/gtk-doc-manual/stable/settingup_vcs.html.en">v systému pro správu verzí</link>.

note: (itstool) path: section/p
en: gtk-doc’s <code>no-tmpl</code> flavour should be used, and XML mode should be used instead of SGML. (tmpl mode and SGML are both outdated and slower than XML.)
cs: Měli byste používat variantu gtk-doc <code>no-tmpl</code> a režim XML namísto SGML. (Režim tmpl a SGML jsou zastaralé a pomalejší než XML.)

note: (itstool) path: section/p
en: If the package version is needed to be substituted into the documentation, create a file named <file>docs/version.xml.in</file>, containing:
cs: Když je zapotřebí vložit číslo balíčku do textu dokumentace, vytvořte soubor s názvem <file>docs/version.xml.in</file>, který bude obsahovat:

note: (itstool) path: section/p
en: Add it to <code>AC_CONFIG_FILES</code> in <file>configure.ac</file>, then include it into the main documentation file (<file>*-docs.xml</file>) using: <code>&lt;!ENTITY version SYSTEM "version.xml"&gt;</code> in the <code>DOCTYPE</code> at the top of the document. The package version can then be used inline as <code>&amp;version;</code>.
cs: Přidejte jej do <code>AC_CONFIG_FILES</code> v <file>configure.ac</file> a pak jej vložte do hlavního souboru dokumentace (<file>*-docs.xml</file>) pomocí: <code>&lt;!ENTITY version SYSTEM "version.xml"&gt;</code> v <code>DOCTYPE</code> na začátku dokumentu. Verzi balíčku pak můžete vkládat pomocí <code>&amp;version;</code>.

note: (itstool) path: section/title
en: Standard Layout
cs: Standardní uspořádání

note: (itstool) path: section/p
en: Using a standard layout for the table of contents, sections, appendices, etc. means the same <file><var>project-name</var>-docs.xml</file> template can be reused with few changes between projects. It also means the documentation layout is similar across all projects, making it more familiar to developers.
cs: Použití standardního uspořádání pro obsah, oddíly, dodatky atd. znamená, že stejnou šablonu <file><var>název-projektu</var>-docs.xml</file> můžete znovu použít s minimálními změnami pro různé projekty. A rovněž to znamená, že uspořádání dokumentace bude obdobné napříč všemi projekty, takže se v ní vývojáři budou lépe orientovat.

note: (itstool) path: section/p
en: The following layout is suggested:
cs: Je doporučováno následující uspořádání:

note: (itstool) path: listing/title
en: <file><var>project-name</var>-docs.xml</file>
cs: <file><var>název-projektu</var>-docs.xml</file>

note: (itstool) path: listing/desc
en: A template top-level gtk-doc file for a project
cs: Soubor gtk-doc s šablonou nejvyšší úrovně pro projekt

note: (itstool) path: section/title
en: Licensing
cs: Licencování

note: (itstool) path: section/p
en: It is important to make the license used for API references clear, especially if they contain code examples which could be copied around.
cs: Je důležité, aby licence použitá pro referenční příručku k API, byla čistá, hlavně když je součástí dokumentace i ukázkový kód, který je možné kopírovat.

note: (itstool) path: section/p
en: Typically, projects use the same license for their API reference as for the project’s code itself, to avoid confusion. Some other projects use CC-BY-SA 3.0 for all their reference documentation. The choice is yours.
cs: Typicky používá projekt pro svoji referenční příručku tu stejnou licenci, jako pro vlastní kód projektu, aby se předešlo nejasnostem. Některé projekty zase používají pro veškerou svoji dokumentaci CC-BY-SA 3.0. Volba je čistě na vás.

note: (itstool) path: section/p
en: As shown in the <link xref="#standard-layout">Standard Layout</link> you should include a <file>license.xml</file> in the top-level gtk-doc DocBook file which gives the full text of your documentation license.
cs: Jak je ukázáno ve <link xref="#standard-layout">Standardním uspořádání</link>, měli byste do souboru gtk-doc DocBook nejvyšší úrovně vložit <file>licence.xml</file>, který poskytne úplný text licence vaší dokumentace.

note: (itstool) path: section/title
en: Public APIs
cs: Veřejná API

note: (itstool) path: section/p
en: All public APIs must have gtk-doc comments. For functions, these should be placed in the source file, directly above the function.
cs: Veškerá veřejná API musí mít komentáře gtk-doc. Pro funkce by měly být umístěny ve zdrojovém souboru, přímo nad funkcí.

note: (itstool) path: section/p
en: Documentation comments for macros, function types, class structs, etc. should be placed next to the definitions, typically in header files.
cs: Dokumentační komentáře pro makra, typy funkcí, struktury tříd atd. by měly být umístěny vedle definici, typicky v hlavičkových souborech.

note: (itstool) path: section/p
en: Section introductions should be placed in the source file they describe, after the license header:
cs: Úvody k jednotlivým oddílům by měly být umístěné ve zdrojových souborech, které popisují, za hlavičkou s licencí:

note: (itstool) path: section/p
en: Keep in mind that in order to include a function, macro, function type, or struct type, it needs to be listed in your documentation’s <file>modulename-sections.txt</file> file.
cs: Mějte na paměti, že aby se funkce, makro, typ funkce nebo typ struktura byly součástí, je zapotřebí je uvést v souboru <file>modulename-sections.txt</file> vaší dokumentace.

note: (itstool) path: section/p
en: To properly document a new class, it needs to be given its own section in <file>modulename-sections.txt</file>, needs to be included in your toplevel <file>modulename-docs.sgml</file>, and the <code>get_type()</code> function for your class needs to be listed in your <file>modulename.types</file>.
cs: Správné zdokumentování nové třídy vyžaduje poskytnutí jejího vlastního oddílu v <file>modulename-sections.txt</file>, musí být vložená v vašem <file>modulename-docs.sgml</file> nejvyšší úrovně a funkce <code>get_type()</code> pro vaši třídu musí být uvedená v <file>modulename.types</file>.

note: (itstool) path: section/title
en: Introspection Annotations
cs: Poznámky k introspekci

note: (itstool) path: section/p
en: Each gtk-doc comment should have appropriate <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations"> GObject introspection annotations</link>. These are useful for two reasons:
cs: Každý komentář gtk-doc by měl mít příslušné <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations">anotace k introspekci GObject</link>. To je užitečné ze dvou důvodů:

note: (itstool) path: item/p
en: They add important information about parameter types, nullability and memory management to the C API documentation generated by gtk-doc.
cs: Přidá to důležitou informaci o typech parametrů, možných prázdných hodnotách a správě paměti do dokumentace k API C vygenerované pomocí gtk-doc.

note: (itstool) path: item/p
en: They allow public APIs to be automatically bound in other languages, such as Python or JavaScript.
cs: Umožní to veřejným API navázat se automaticky na další jazyky, jako třeba Python nebo JavaScript.

note: (itstool) path: section/p
en: Introspection annotations add information to APIs (functions, function parameters, function return values, structures, GObject properties, GObject signals) which is otherwise not present in the machine readable C API and only exists in the form of human readable documentation or convention. They are very important.
cs: Anotace k introspekci přidává do API (funkce, parametry funkcí, návratové hodnoty funkcí, struktury, vlastnosti GObject, signály GObject) informace, které ve strojově čitelné podobě API v C nejsou jinak dostupné a existují jen ve formě čitelné člověkem v dokumentaci nebo jako zvyklosti. Proto jsou velmi důležité.

note: (itstool) path: section/p
en: In gtk-doc comments, annotations should be preferred over human-readable equivalents. For example, when documenting a function parameter which may be <code>NULL</code>, use the <code>(nullable)</code> annotation rather than some text:
cs: V komentářích gtk-doc by se měla dávat přednost anotacím před variantou čitelnou pro člověka. Například, když dokumentujete parametr funkce, který může nabývat hodnoty <code>NULL</code>, použijte namísto nějakého textu raději anotaci <code>(nullable)</code>:

note: (itstool) path: section/p
en: Instead of:
cs: Použijte namísto:

note: (itstool) path: section/p
en: For more information on introspection, see the <link xref="introspection">introspection guidelines</link>.
cs: Více informací k introspekci najdete v <link xref="introspection">pokynech k introspekci</link>.

note: (itstool) path: section/title
en: Symbol Versioning
cs: Číslování verzí symbolů

note: (itstool) path: section/p
en: Whenever a symbol is added to the public API, it should have a documentation comment added. This comment should always contain a <code>Since</code> line with the package version number of the release which will first contain the new API. This should be the number currently in <file>configure.ac</file> if <link xref="versioning#release-process">post-release version incrementing</link> is being used.
cs: Kdykoliv je do veřejného API přidán nějaký symbol, měl by pro něj být přidán i dokumentační komentář. Ten by měl vždy obsahovat řádek <code>Since</code> s číslem verze vydání balíčku, který poprvé obsahuje nové API. Mělo by se jednat o číslo verze, které se právě nachází v <file>configure.ac</file>, za předpokladu, že používáte <link xref="versioning#release-process">zvyšování čísla verze po vydání</link>.

note: (itstool) path: section/p (itstool) path: example/p
en: For example:
cs: Například:

note: (itstool) path: section/p
en: gtk-doc uses this information to generate indexes of the APIs added in each release. These should be added to the main <file>*-docs.xml</file> as an appendix:
cs: gtk-doc používá tyto informace k vygenerování rejstříku API přidaných v jednotlivých vydáních. Do <file>*-docs.xml</file> by jako dodatek mělo být přidáno následující:

note: (itstool) path: section/title
en: D-Bus APIs
cs: API pro D-Bus

note: (itstool) path: section/p
en: D-Bus interface descriptions contain documentation comments, and these can be extracted from the XML using <cmd>gdbus-codegen</cmd>, and turned into DocBook files to be included by gtk-doc.
cs: Popisy rozhraní D-Bus obsahují dokumentační komentáře a ty je možné získat z XML pomocí <cmd>gdbus-codegen</cmd> a nasměrovat do souborů DocBook, aby byly začleněny pomocí gtk-doc.

note: (itstool) path: section/p
en: The DocBook files can be included in the main <file>*-docs.xml</file> file using:
cs: Soubory DocBook mohou být vloženy do souboru <file>*-docs.xml</file> pomocí:

note: (itstool) path: section/p
en: The generated XML files must be included in the <code>content_files</code> variable in your gtk-doc <file>Makefile.am</file>, otherwise the build will fail. (This is to fix situations where the <code>builddir</code> does not equal the <code>srcdir</code>.)
cs: Vygenerované soubory XML musí být zahrnuté v proměnné <code>content_files</code> ve vašem <file>Makefile.am</file> pro gtk-doc, jinak sestavení selže. (Je to kvůli nápravě situací, kdy složka <code>builddir</code> není shodná se <code>srcdir</code>.)

note: (itstool) path: section/title
en: Keeping Documentation Up to Date
cs: Udržování dokumentace v aktuálním stavu

note: (itstool) path: section/p
en: gtk-doc comes with support for checking the documentation with some basic tests. These check that all version indexes are included in the main <file>*-docs.xml</file> file and that all symbols are documented, among other things.
cs: gtk-doc obsahuje podporu pro kontrolu dokumentace pomocí pár základních testů. Mimo jiných věcí se zkontroluje, jestli jsou všechny verze indexů vložené v hlavním souboru <file>*-docs.xml</file> a jestli jsou zdokumentované všechny symboly.

note: (itstool) path: section/p
en: These tests should always be enabled, by adding the following to your gtk-doc <file>Makefile.am</file>:
cs: Tyto testy by měly být vždy povolené přidáním následujícího do <file>Makefile.am</file> pro váš gtk-doc:

note: (itstool) path: section/p
en: They will then be run as part of <cmd>make check</cmd>.
cs: Budou pak spouštěny jako součást <cmd>make check</cmd>.

note: (itstool) path: info/desc
en: Accessing the file system
cs: Jak přistupovat k souborovému systému

note: (itstool) path: page/title
en: File System Access
cs: Přístup k souborovému systému

note: (itstool) path: synopsis/p
en: There are a few anti-patterns to consider when accessing the file system. This article assumes knowledge of the standard <link href="https://developer.gnome.org/gio/stable/GFile.html"><code>GFile</code></link>, <link href="https://developer.gnome.org/gio/stable/GInputStream.html"><code>GInputStream</code></link> and <link href="https://developer.gnome.org/gio/stable/GOutputStream.html"><code>GOutputStream</code></link> APIs.
cs: Při přístupu k souborovému systému byste měli mít na paměti několik negativních návrhových vzorů. Tento článek předpokládá znalost standardních API <link href="https://developer.gnome.org/gio/stable/GFile.html"><code>GFile</code></link>, <link href="https://developer.gnome.org/gio/stable/GInputStream.html"><code>GInputStream</code></link> a <link href="https://developer.gnome.org/gio/stable/GOutputStream.html"><code>GOutputStream</code></link>.

note: (itstool) path: item/p
en: Use asynchronous I/O for file access. (<link xref="#asynchronous-io"/>)
cs: Pro přístup k souborům používejte asynchronní V/V. (<link xref="#asynchronous-io"/>)

note: (itstool) path: item/p
en: Always use appropriate functions to construct file names and paths. (<link xref="#file-path-construction"/>)
cs: Vždy používejte vhodné funkce k vytvoření názvů souborů a cest. (<link xref="#file-path-construction"/>)

note: (itstool) path: item/p
en: Validate file paths are in the expected directories before using them. (<link xref="#path-validation-and-sandboxing"/>)
cs: Než použijete cestu k souboru, ověřte, že se nachází v očekávané složce. (<link xref="#path-validation-and-sandboxing"/>)

note: (itstool) path: item/p
en: Use mandatory access control profiles to enforce constraints on file access. (<link xref="#path-validation-and-sandboxing"/>)
cs: Používejte povinné profily pro řízení přístupu, aby se zaručily omezení v přístupu k souborům. (<link xref="#path-validation-and-sandboxing"/>)

note: (itstool) path: section/title
en: Asynchronous I/O
cs: Asynchronní V/V

note: (itstool) path: section/p
en: Almost all I/O should be performed asynchronously. That is, without blocking the <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html">GLib main context</link>. This can be achieved by always using the <code>*_async()</code> and <code>*_finish()</code> variants of each I/O function.
cs: Většina V/V operací by měla být prováděna asynchronně. Což znamená bez blokování <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html">hlavního kontextu GLib</link>. Toho lze dosáhnout důsledným používáním variant <code>*_async()</code> a <code>*_finish()</code> jednotlivých V/V funkcí.

note: (itstool) path: example/p
en: For example, <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-async"><code>g_input_stream_read_async()</code></link> rather than <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read"><code>g_input_stream_read()</code></link>.
cs: Například použijte <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-async"><code>g_input_stream_read_async()</code></link> a ne <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read"><code>g_input_stream_read()</code></link>.

note: (itstool) path: section/p
en: Synchronous I/O blocks the main loop, which means that other events, such as user input, incoming networking packets, timeouts and idle callbacks, are not handled until the blocking function returns.
cs: Synchronní V/V operace blokují hlavní smyčku, což znamená, že ostatní události, jako je vstup od uživatele, příchozí síťový paket, vypršení časového limitu a zpětné volání při nečinnosti, nejsou obsluhovány, dokud nedojde k návratu z blokující funkce.

note: (itstool) path: section/p
en: Synchronous I/O is acceptable in certain circumstances where the overheads of scheduling an asynchronous operation exceed the costs of local synchronous I/O on Linux. For example, making a small read from a local file, or from a virtual file system such as <file>/proc</file>. For such reads, the low level functions <code>g_open()</code>, <code>read()</code> and <code>g_close()</code> should be used rather than GIO.
cs: Synchronní V/V je přijatelný za určitých okolností, kdy náklady na plánování asynchronní operace převýší cenu místního synchronního V/V v Linuxu. Například provedení drobného čtení z místního souborového systému nebo z virtuálního souborového systému, jako je <file>/proc</file>. Při takovém čtení by měly být použity raději nízkoúrovňové funkce <code>g_open()</code>, <code>read()</code> a <code>g_close()</code> místo GIO.

note: (itstool) path: section/p
en: Files in the user’s home directory do <em>not</em> count as local, as they could be on a networked file system.
cs: Soubory v uživatelově domovské složce se <em>nepočítají</em> jako místní, protože mohou být na síťovém souborovém systému.

note: (itstool) path: section/p
en: Note that the alternative – running synchronous I/O in a separate thread – is highly discouraged; see the <link xref="threading#when-to-use-threading">threading guidelines</link> for more information.
cs: Upozorňujeme, že alternativa – běh synchronního V/V v odděleném vlákně – je silně nedoporučován. Více informací viz <link xref="threading#when-to-use-threading">pokyny k vláknům</link>.

note: (itstool) path: section/title
en: File Path Construction
cs: Sestavení cesty k souboru

note: (itstool) path: section/p
en: File names and paths are not normal strings: on some systems, they can use a character encoding other than UTF-8, while normal strings in GLib are guaranteed to always use UTF-8. For this reason, special functions should be used to build and handle file names and paths. (Modern Linux systems almost universally use UTF-8 for filename encoding, so this is not an issue in practice, but the file path functions should still be used for compatibility with systems such as Windows, which use UTF-16 filenames.)
cs: Názvy souborů a cesty nejsou běžné řetězce: na některých systémech mohou používat jiné kódování znaků, než UTF-8, zatímco u normálních řetězců je v GLib vždy zaručeno použití UTF-8. Z tohoto důvodu by pro sestavení a zpracování názvů souborů a cest měly používat speciální funkce. (Moderní linuxové systémy povětšinou pro kódování názvů souborů jednotně používají UTF-8, takže to v praxi není problém, ale tyto funkce by měly být přesto používány kvůli kompatibilitě s jinými systéme, jako jsou Windows používající v názvech souborů UTF-16.)

note: (itstool) path: example/p
en: For example, file paths should be built using <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-build-filename"><code>g_build_filename()</code></link> rather than <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strconcat"><code>g_strconcat()</code></link>.
cs: Například cesta k souboru by se měla sestavit pomocí <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-build-filename"><code>g_build_filename()</code></link> namísto běžného <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strconcat"><code>g_strconcat()</code></link>.

note: (itstool) path: section/p
en: Doing so makes it clearer what the code is meant to do, and also eliminates duplicate directory separators, so the returned path is canonical (though not necessarily absolute).
cs: Když se to dělá takto, je v kódu jasnější, co se tím míní a také se tím zamezí zdvojení oddělovačů cest a vrácená cesta je kanonická (i když ne nutně absolutně).

note: (itstool) path: example/p
en: As another example, paths should be disassembled using <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-basename"><code>g_path_get_basename()</code></link> and <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-dirname"><code>g_path_get_dirname()</code></link> rather than <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strrstr"><code>g_strrstr()</code></link> and other manual searching functions.
cs: Jiným příkladem by mohlo být rozložení cesty pomocí <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-basename"><code>g_path_get_basename()</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-dirname"><code>g_path_get_dirname()</code></link> namísto běžného <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strrstr"><code>g_strrstr()</code></link> nebo jiných ručních vyhledávacích funkcí.

note: (itstool) path: section/title
en: Path Validation and Sandboxing
cs: Ověřování cest a pískoviště

note: (itstool) path: section/p
en: If a filename or path comes from external input, such as a web page or user input, it should be validated to ensure that putting it into a file path will not produce an arbitrary path. For example if a filename is constructed from the constant string <file>~/</file> plus some user input, if the user inputs <file>../../etc/passwd</file>, they can (potentially) gain access to sensitive account information, depending on which user the program is running as, and what it does with data loaded from the constructed path.
cs: Když název souboru nebo cesta pochází z externího vstupu, jako je webová stránka nebo uživatelský vstup, měly by být ověřeny, aby se zajistilo, že jejich vložení do cesty nevytvoří jen tak nějakou cestu. Například, když je název souboru sestavován z řetězce <file>~/</file> plus uživatelského vstupu a uživatel zadá <file>../../etc/passwd</file>, mohl by (potenciálně) získat přístup k citlivým informacím o účtech, v závislosti na tom, pod jakým účtem program běží a co dělá s daty načtenými ze sestavené cesty.

note: (itstool) path: section/p
en: This can be avoided by validating constructed paths before using them, using <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-resolve-relative-path"><code>g_file_resolve_relative_path()</code></link> to convert any relative paths to absolute ones, and then validating that the path is beneath a given root sandboxing directory appropriate for the operation. For example, if code downloads a file, it could validate that all paths are beneath <file>~/Downloads</file>, using <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-has-parent"><code>g_file_has_parent()</code></link>.
cs: Tomu se dá předejít ověřováním sestavené cesty před tím, než ji použijete, pomocí funkce <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-resolve-relative-path"><code>g_file_resolve_relative_path()</code></link>, která převede relativní cesty na absolutní a následně ověří, že cesta je pod danou kořenovou složku pískoviště příslušejícího operaci. Například, když kód stahuje soubor, mohl by pomocí <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-has-parent"><code>g_file_has_parent()</code></link> ověřovat, že jsou všechny cesty pod <file>~/Downloads</file>.

note: (itstool) path: section/p
en: As a second line of defense, all projects which access the file system should consider providing a mandatory access control profile, using a system such as <link href="http://apparmor.net/">AppArmor</link> or <link href="http://selinuxproject.org/">SELinux</link>, which limits the directories and files they can read from and write to.
cs: Jako druhou linii obrany by všechny projekty, které přistupují k souborovému systému, měly zvážit poskytnutí povinného profilu pro řízení přístupu za použití systému jako jsou <link href="http://apparmor.net/">AppArmor</link> nebo <link href="http://selinuxproject.org/">SELinux</link>, čímž se omezí složky a soubory, které lze číst a zapisovat do nich.

note: (itstool) path: info/desc
en: Runtime error handling and reporting
cs: Obsluha a hlášení běhových chyb

note: (itstool) path: section/title
en: GError Usage
cs: Použití GError

note: (itstool) path: section/p
en: <link href="https://developer.gnome.org/glib/stable/glib-Error-Reporting.html"><code>GError</code></link> is the standard error reporting mechanism for GLib-using code, and can be thought of as a C implementation of an <link href="https://en.wikipedia.org/wiki/Exception_handling">exception</link>.
cs: <link href="https://developer.gnome.org/glib/stable/glib-Error-Reporting.html"><code>GError</code></link> je standardní mechanizmus hlášení chyb pro kód používající GLib a může na něj být pohlíženo jako na implementaci <link href="https://cs.wikipedia.org/wiki/V%C3%BDjimka_(programov%C3%A1n%C3%AD)">výjimek</link> v jazyce C.

note: (itstool) path: section/p
en: Any kind of runtime failure (anything which is not a <link xref="preconditions">programmer error</link>) must be handled by including a <code>GError**</code> parameter in the function, and setting a useful and relevant GError describing the failure, before returning from the function. Programmer errors must not be handled using GError: use assertions, pre-conditions or post-conditions instead.
cs: Libovolný druh selhání za běhu (cokoliv, co není <link xref="preconditions">programová chyba</link>) musí být obslouženo vložením parametru <code>GError**</code> do funkce a před návratem z funkce nastavením vhodného a smysluplného popisu selhání v GError. Programové chyby se naopak pomocí GError obsluhovat nesmí: místo toho použijte assertion a podmíněné testy před a po.

note: (itstool) path: section/p
en: GError should be used in preference to a simple return code, as it can convey more information, and is also supported by all GLib tools. For example, <link xref="introspection">introspecting an API</link> will automatically detect all GError parameters so that they can be converted to exceptions in other languages.
cs: Použití GError byste měli dávat přednost před prostým návratem kódu, protože poskytuje více informací a navíc je podporován všemi nástroji GLib. Například <link xref="introspection">introspekce API</link> bude automaticky detekovat všechny parametry GError, protože je pak umí převést na výjimky v jiných jazycích.

note: (itstool) path: section/p
en: Printing warnings to the console must not be done in library code: use a GError, and the calling code can propagate it further upwards, decide to handle it, or decide to print it to the console. Ideally, the only code which prints to the console will be top-level application code, and not library code.
cs: Výpis varování do konzole se nesmí provádět v programovém kódu knihovny. Použijte GError a volající kód jej může propagovat dále, rozhodnout se jej zpracovat nebo se rozhodnout jej vypsat do konzole. V ideálním případě je jediným kódem, který vypisuje do konzole, programový kód nejvyšší úrovně aplikace a ne kód knihovny.

note: (itstool) path: section/p
en: Any function call which can take a <code>GError**</code>, <em>should</em> take such a parameter, and the returned GError should be handled appropriately. There are very few situations where ignoring a potential error by passing <code>NULL</code> to a <code>GError**</code> parameter is acceptable.
cs: Volání kterékoliv funkce, které přebírá <code>GError**</code>, <em>by mělo</em> takovýto parametr poskytnout a pak příslušně obsloužit vrácený GError. Je jen velmi málo situací, kdy je přijatelné potenciální chybu ignorovat předáním <code>NULL</code> do parametru <code>GError**</code>.

note: (itstool) path: section/p
en: The GLib API documentation contains a <link href="https://developer.gnome.org/glib/stable/glib-Error-Reporting.html#glib-Error-Reporting.description">full tutorial for using GError</link>.
cs: Dokumentace k API knihovny GLib obsahuje <link href="https://developer.gnome.org/glib/stable/glib-Error-Reporting.html#glib-Error-Reporting.description">uceleného průvodce použitím GError</link>.

note: (itstool) path: info/desc
en: Linked lists and container types
cs: Propojené seznamy a kontejnerové typy

note: (itstool) path: section/title
en: GList Usage
cs: Použití GList

note: (itstool) path: section/p
en: GLib provides several container types for sets of data: <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html"><code>GList</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html"><code>GSList</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html"><code>GPtrArray</code></link> and <link href="https://developer.gnome.org/glib/stable/glib-Arrays.html"><code>GArray</code></link>.
cs: GLib poskytuje někoklik kontejnerových typů pro množiny dat: <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html"><code>GList</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html"><code>GSList</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html"><code>GPtrArray</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Arrays.html"><code>GArray</code></link>.

note: (itstool) path: section/p
en: It has been common practice in the past to use GList in all situations where a sequence or set of data needs to be stored. This is inadvisable — in most situations, a GPtrArray should be used instead. It has lower memory overhead (a third to a half of an equivalent list), better cache locality, and the same or lower algorithmic complexity for all common operations. The only typical situation where a GList may be more appropriate is when dealing with ordered data, which requires expensive insertions at arbitrary indexes in the array.
cs: Dříve bylo běžnou praxí používat GList ve všech situacích, kdy bylo zapotřebí uchovat řadu nebo množinu dat. To ale není rozumné — ve většině situací by místo něj měl být použit GPtrArray. Má menší paměťové nároky (třetinové až poloviční oproti obdobnému seznamu), lepší dostupnost z mezipaměti a stejnou nebo menší algoritmickou složitost pro všechny běžné operace. Jedinou typickou situací, kdy může být GList vhodnější, je při práci se uspořádanými daty ve kterých je požadováno masivní vkládání na libovolné místo v poli.

note: (itstool) path: section/p
en: If linked lists are used, be careful to keep the complexity of operations on them low, using standard CS complexity analysis. Any operation which uses <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth"><code>g_list_nth()</code></link> or <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth-data"><code>g_list_nth_data()</code></link> is almost certainly wrong. For example, iteration over a GList should be implemented using the linking pointers, rather than a incrementing index:
cs: Když jsou použité zřetězené seznamy, dávejte pozor, aby složitost operací zůstala na rozumné úrovni podle standardní analýzy složitosti v matematické informatice. Kterákoliv operace, která používá <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth"><code>g_list_nth()</code></link> nebo <link href="https://developer.gnome.org/glib/2.30/glib-Doubly-Linked-Lists.html#g-list-nth-data"><code>g_list_nth_data()</code></link>, je povětšinou úplně špatně. Například iterace přes GList by měla být implementována pomocí zřetězujících ukazatelů a ne postupným zvyšováním indexu.

note: (itstool) path: section/code
en: GList *some_list, *l;
    
    for (l = some_list; l != NULL; l = l-&gt;next)
      {
        gpointer element_data = l-&gt;data;
    
        /* Do something with @element_data. */
      }
cs: GList *some_list, *l;
    
    for (l = some_list; l != NULL; l = l-&gt;next)
      {
        gpointer element_data = l-&gt;data;
    
        /* Provedení něčeho s @element_data. */
      }

note: (itstool) path: section/p
en: Using an incrementing index instead results in a quadratic decrease in performance (<em>O(N^2)</em> rather than <em>O(N)</em>):
cs: Když se místo toho použije postupné zvyšování indexu, je výsledkem kvadratické snížení výkonu (<em>O(N^2)</em> namísto <em>O(N)</em>):

note: (itstool) path: section/code
en: GList *some_list;
    guint i;
    
    /* This code is inefficient and should not be used in production. */
    for (i = 0; i &lt; g_list_length (some_list); i++)
      {
        gpointer element_data = g_list_nth_data (some_list, i);
    
        /* Do something with @element_data. */
      }
cs: GList *some_list;
    guint i;
    
    /* Tento algoritmus je neefektivní a neměl by být použit v produkčním kódu. */
    for (i = 0; i &lt; g_list_length (some_list); i++)
      {
        gpointer element_data = g_list_nth_data (some_list, i);
    
        /* Provedení něčeho s @element_data. */
      }

note: (itstool) path: section/p
en: The performance penalty comes from <code>g_list_length()</code> and <code>g_list_nth_data()</code> which both traverse the list (<em>O(N)</em>) to perform their operations.
cs: Snížení výkonu nastává ve funkcích <code>g_list_length()</code> a <code>g_list_nth_data()</code>, které obě kvůli provedení své operace pole procházejí (<em>O(N)</em>).

note: (itstool) path: section/p
en: Implementing the above with a GPtrArray has the same complexity as the first (correct) GList implementation, but better cache locality and lower memory consumption, so will perform better for large numbers of elements:
cs: Implementace kódu uvedeného výše pomocí GPtrArray má stejnou složitost pro první (správnou) implementaci GList, ale lepší dostupnost z mezipaměti a nižší spotřebu paměti, takže bude mít lepší výkon pro velké množství prvků:

note: (itstool) path: section/code
en: GPtrArray *some_array;
    guint i;
    
    for (i = 0; i &lt; some_array-&gt;len; i++)
      {
        gpointer element_data = some_array-&gt;pdata[i];
    
        /* Do something with @element_data. */
      }
cs: GPtrArray *some_array;
    guint i;
    
    for (i = 0; i &lt; some_array-&gt;len; i++)
      {
        gpointer element_data = some_array-&gt;pdata[i];
    
        /* Provedení něčeho s @element_data. */
      }

note: (itstool) path: credit/name
en: GNOME Foundation
cs: Nadace GNOME

note: (itstool) path: info/desc (itstool) path: page/title
en: GNOME Programming Guidelines
cs: Pokyny k programování GNOME

[ctx: link:trail]
note: (itstool) path: info/title
en: Programming Guidelines
cs: Pokyny k programování

note: (itstool) path: page/p
en: This article contains several guidelines and suggestions for programmers working in and with the GNOME stack. This is intended for programmers to know about the development processes, conventions and philosophies behind GNOME applications and the stack of libraries supporting them. By knowing “the way things are done” in the GNOME ecosystem, it is hoped that programmers will find use of GNOME APIs and development of new applications easier and more natural, and will produce code which is legible and maintainable over a long period of time by a diverse team of programmers.
cs: Tato příručka obsahuje několik pokynů a doporučení pro programátory pracující s GNOME. Je zaměřena na programátory, kteří mají povědomí o procesu vývoje, zvyklostech a filozofii stojící za aplikacemi GNOME a hromadou knihoven, které jim poskytují podporu. Doufáme, že díky znalosti „jak se to dělá“ v ekosystému GNOME, shledají programátoři použití různých API v GNOME a vývoj nových aplikací jednodušším a přirozenějším a budou vytvářet kód, který je čitelný a udržovatelný po dlouhou dobu různorodým týmem programátorů.

note: (itstool) path: page/p
en: This guide has a two-fold purpose:
cs: Tato příručka má dvojí účel:

note: (itstool) path: item/p
en: To give you good suggestions on how to write code for GNOME or using GNOME technologies. This will help you write code that is consistent with best practices, and that will be accepted by the community. This will also lead to code that is a pleasure to work on.
cs: Poskytnout vám dobrá doporučení, jak psát kód pro GNOME a s použitím technologií GNOME. Pomůže vám to psát kód, který je v souladu s nejlepšími zvyklostmi a který bude přijat komunitou. Zavede vás to do světa kódu, na kterém je potěšením pracovat.

note: (itstool) path: item/p
en: To transmit the knowledge we have gotten over the years on how to keep the GNOME project sustainable, even when people’s contributions increase or decrease.
cs: Přinést znalosti, které jsme nasbírali v průběhu let, kdy jsem se snažili udržet projekt GNOME dlouhodobě fungující, i když se počet přispívajících lidí zvyšoval nebo snižoval.

[ctx: link:trail]
note: (itstool) path: info/title
en: General Guidelines
cs: Obecné pokyny

note: (itstool) path: section/title
en: General Guidelines
cs: Obecné pokyny

[ctx: link:trail]
note: (itstool) path: info/title
en: Maintainer Guidelines
cs: Pokyny pro správce

note: (itstool) path: section/title
en: Maintainer Guidelines
cs: Pokyny pro správce

[ctx: link:trail]
note: (itstool) path: info/title
en: Specific How-Tos
cs: Jak na to konkrétněji

note: (itstool) path: section/title
en: Specific How-Tos
cs: Jak na to konkrétněji

[ctx: link:trail]
note: (itstool) path: info/title
en: References
cs: Odkazy

note: (itstool) path: section/title
en: References
cs: Odkazy

note: (itstool) path: info/desc
en: GObject Introspection support in library code
cs: Podpora introspekce pro GObject v kódu knihovny

note: (itstool) path: page/title
en: Introspection
cs: Introspekce

note: (itstool) path: synopsis/p
en: <link href="https://wiki.gnome.org/Projects/GObjectIntrospection"> GObject introspection</link> (abbreviated ‘GIR’) is a system which extracts APIs from C code and produces binary type libraries which can be used by non-C language bindings, and other tools, to <link href="https://en.wikipedia.org/wiki/Type_introspection">introspect</link> or <link href="https://en.wikipedia.org/wiki/Language_binding">wrap</link> the original C libraries. It uses a system of annotations in documentation comments in the C code to expose extra information about the APIs which is not machine readable from the code itself.
cs: <link href="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject introspection</link> (zkráceně „GIR“) je systém, který získává API z kódu v jazyce C a na jejich základě vytváří binární knihovny, které můžete použít k navázání jiných programovacích jazyků a v nástrojích pro <link href="https://en.wikipedia.org/wiki/Type_introspection">introspekci</link> nebo <link href="https://cs.wikipedia.org/wiki/Language_Binding">navázání</link> originálních knihoven v C. Používá se k tomu systém anotací v dokumentačních komentářích ve zdrojových kódech, pomocí kterých se zveřejní doplňující informace o API, které jsou přímo z kódu strojově čitelné.

note: (itstool) path: synopsis/p
en: It should be enabled for all public APIs: so all libraries. It cannot be enabled for programs, since they expose no APIs. However, it is still recommended to <link xref="documentation#introspection-annotations">add introspection annotations to documentation comments</link> in program code, as they clarify the documentation.
cs: Mělo by to být zapnuto pro všechna veřejná API, tzn. pro všechny knihovny. Zapnuto by to nemělo být pro programy, protože ty nevystavují žádná API. I tak je ale doporučeno <link xref="documentation#introspection-annotations">přidat anotace k introspekci do dokumentačních komentářů</link> v programovém kódu, aby dokumentace byla jasnější.

note: (itstool) path: item/p
en: Enable introspection for all libraries. (<link xref="#using-introspection"/>)
cs: Povolte introspekci pro všechny knihovny. (<link xref="#using-introspection"/>)

note: (itstool) path: item/p
en: Pay attention to warnings from <cmd>g-ir-scanner</cmd> and <code>introspectable="0"</code> attributes in GIR files. (<link xref="#using-introspection"/>)
cs: Dávejte pozor na varování od <cmd>g-ir-scanner</cmd> a atribut <code>introspectable="0"</code> v souborech GIR. (<link xref="#using-introspection"/>)

note: (itstool) path: item/p
en: Add introspection annotations to all documentation comments. (<link xref="#using-introspection"/>)
cs: Přidávejte anotace k introspekci do všech dokumentačních komentářů. (<link xref="#using-introspection"/>)

note: (itstool) path: item/p
en: Design APIs to be introspectable from the start. (<link xref="#api-design"/>)
cs: Navrhujte API už od začátku tak, aby v nich šla použít introspekce. (<link xref="#api-design"/>)

note: (itstool) path: section/title
en: Using Introspection
cs: Použití introspekce

note: (itstool) path: section/p
en: The first step for using introspection is to add it to the build system, following the instructions <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/AutotoolsIntegration#Method_1_-_Recommended_-_most_portable">here</link>, following method 1. This should be done early in the life of a project, as introspectability affects <link xref="#api-design">API design</link>.
cs: Prvním korkem k použití introspekce je její přidání do sestavovacího systému podle instrukcí uvedených <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/AutotoolsIntegration#Method_1_-_Recommended_-_most_portable">zde</link> v metodě 1. Mělo by se tak stát v rané fázi projektu, protože schopnost introspekce ovlivňuje <link xref="#api-design">návrh API</link>.

note: (itstool) path: section/p
en: This should result in a <file>.gir</file> and <file>.typelib</file> file being generated for the project. The <file>.gir</file> file is human readable, and can be inspected manually to see if the API has been introspected correctly (although the GIR compilation process will print error messages and warnings for any missing annotations or other problems). APIs with <code>introspectable="0"</code> will not be exposed to language bindings as they are missing annotations or are otherwise not representable in the GIR file.
cs: To by se mělo odrazit v souborech <file>.gir</file> a <file>.typelib</file>, které se pro projekt vygenerují. Soubor <file>.gir</file> je člověkem čitelný a můžete jej ručně zkoumat, jestli má API správnou introspekci (ačkoliv proces kompilace GIR vypíše chybové zprávy a varování pro chybějící anotace nebo jiné problémy). API s <code>introspectable="0"</code> nebude zpřístupněno pro vazbu na jazyk, protože mu schází anotace nebo není z jiných důvodů přítomno v souboru GIR.

note: (itstool) path: section/p
en: The next step is to <link xref="documentation#introspection-annotations">add annotations to the documentation comments for every piece of public API</link>. If a particular piece of API should not be exposed in the GIR file, use the <code>(skip)</code> annotation. Documentation on the available annotations is <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations">here</link>.
cs: Dalším krokem je <link xref="documentation#introspection-annotations">přidat anotace do dokumentačních komentářů pro každou část veřejného API</link>. Pokud některá konkrétní část nemá být v souboru GIR zpřístupněna, použijte anotaci <code>(skip)</code>. Dokumentaci se seznamem dostupných anotací najdete <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations">zde</link>.

note: (itstool) path: section/p
en: If annotating the code for a program, a good approach is to split the bulk of the code out into an internal, private convenience library. An internal API reference manual can be built from its documentation comments (see <link xref="documentation"/>). The library is then not installed, but is linked in to the program which is itself installed. This approach for generating internal API documentation is especially useful for large projects where the internal code may be large and hard to navigate.
cs: Když vytváříte anotace kódu pro program, je dobrým zvykem rozdělik hromadu kódu do vhodných interních privátních knihoven. Z dokumentačních komentářů pak můžete sestavit referenční příručku k API (viz <link xref="documentation"/>). Takovéto knihovny se pak neinstalují, ale přímo slinkují s vlastním programem. Přínos vygenerované interní dokumentace oceníte především u velkých projektů, kde interní kód může být opravdu rozsáhlý a těžko se v něm orientuje.

note: (itstool) path: section/p
en: Annotations do not have to be added exhaustively: GIR has a set of default annotations which it applies based on various conventions (see <link xref="#api-design"/>). For example, a <code>const gchar*</code> parameter does not need an explicit <code>(transfer none)</code> annotation, because the <code>const</code> modifier implies this already. Learning the defaults for annotations is a matter of practice.
cs: Anotace by ale neměly být přidávány bezúčelně: GIR má sadu výchozích anotací, které se použijí na základě různých pravidel (viz <link xref="#api-design"/>). Například parametr <code>const gchar*</code> nepotřebuje výslovně uvádět anotaci <code>(transfer none)</code>, protože to dává najevo již modifikátor <code>const</code>. Když se tyto výchozí anotace naučíte, jen to prospěje věci.

note: (itstool) path: section/title
en: API Design
cs: Návrh API

note: (itstool) path: section/p
en: In order to be introspectable without too many annotations, APIs must follow certain conventions, such as the <link href="https://developer.gnome.org/gobject/stable/gtype-conventions.html">standard GObject naming conventions</link>, and the <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs">conventions for bindable APIs</link>. This is necessary because of the flexibility of C: code can be written to behave in any way imaginable, but higher level languages don’t allow this kind of freedom. So in order for a C API to be representable in a higher level language, it has to conform to the behaviors supported by that language.
cs: Aby API podporovalo introspekci bez přílišného množství anotací, musí dodržovat jisté zvyklosti, jako třeba <link href="https://developer.gnome.org/gobject/stable/gtype-conventions.html">standardní konvenci názvů GObject</link> a <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs">konvenci pro API podporující vazby na jiné jazyky</link>. To je nutné kvůli flexibilitě C: programový kód, který se chová slušně, může být napsán všemožnými způsoby, ale vysokoúrovňové jazyky tento druh volnosti nedovolují. Takže aby API v jazyce C mohlo být zpřístupněno ve vysokoúrovňovém jazyce, musí se podřídit chování podporovanému tímto jazykem.

note: (itstool) path: section/p
en: For example, GIR expects that if a function can fail, it will have a <code>GError**</code> parameter, which will always be its final parameter. The GIR scanner detects this and automatically converts that parameter to an exception attribute on the method in the GIR file. It cannot do this if the <code>GError*</code> is returned directly, or is not the final function parameter, for example.
cs: Například GIR očekává, že jestliže funkce může selhat, tak vrací parametr <code>GError**</code>, který je vždy posledním parametrem. Analyzátor GIR takovýto parametr odhalí a automaticky převede atribut výjimky u metody v souboru GIR. Nemůže to ale udělat, pokud je například  <code>GError**</code> vracen přímo nebo není posledním parametrem.

note: (itstool) path: section/p
en: Therefore, APIs must be designed to be introspectable, and the GIR file should be checked as the APIs are being written. If the GIR doesn’t match what you expect for a new API, the API may need extra annotations, or even for its C declaration to be changed (as in the case of <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs#va_list"><code>va_list</code></link>).
cs: Proto musí být API navržena pro introspekci a při jejich psaní by měl být překontrolováván soubor GIR. Když GIR neodpovídá tomu, co pro nové API očekáváte, potřebuje API dodatečné anotace nebo i změnu v deklaraci C (jako v případě <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs#va_list"><code>va_list</code></link>).

note: (itstool) path: section/p
en: <cmd>g-ir-scanner</cmd> emits warnings when it encounters code it does not understand. By passing <cmd>--warn-error</cmd> as well as <cmd>--warn-all</cmd> in <code>INTROSPECTION_SCANNER_ARGS</code> in <file>Makefile.am</file>, compilation will fail when unintrospectable APIs are encountered. This will ensure all new APIs are introspectable, and is highly recommended.
cs: <cmd>g-ir-scanner</cmd> vyšle varování, když narazí na kód, kterému nerozumí. Předání <cmd>--warn-error</cmd> nebo také <cmd>--warn-all</cmd> v <code>INTROSPECTION_SCANNER_ARGS</code> v <file>Makefile.am</file> způsobí, že kompilace selže, když se narazí na API nepodporující introspekci. Tím se zajistí, že nová API budou vždy podporovat introspekci, což je silně doporučováno.

note: (itstool) path: info/desc
en: Logging debug and information output from libraries and programs
cs: Ladicí záznamy a informační výstup z knihoven a programů

note: (itstool) path: page/title
en: Logging
cs: Záznamy (log)

note: (itstool) path: synopsis/p
en: Logging debug and informational output from libraries and programs is an open problem, and there are various methods for converting multiple streams of log output into the customary stdout and stderr streams. Below are some suggestions for how to implement logging. However, the most important thing is to ensure that logging is consistent, so that log data can be accessed and searched with a minimum of effort, since that’s what it’s used for. Using different logging mechanisms and formats in different projects is not the right approach.
cs: Záznam ladicího a informačního výstupu z knihoven a programů je stále otevřený problém a existuje řada metod pro převod více datových proudů s výstupními záznamy do vlastních datových proudů stdout a stderr. Níže jsou uvedena některá doporučení, jak zaznamenávání implementovat. Nejdůležitější věcí ale je zajistit, aby záznamy byly konzistentní, takže k nim bude jednoduchý přístup a půjde v nich snadno vyhledávat, protože to je přesně to, k čemu slouží. Používat odlišné mechanizmy záznamu a odlišné formáty u různých projektů není ten pravý přístup.

note: (itstool) path: item/p
en: Use the GLib logging framework instead of logging directly to stderr and stdout. (<link xref="#glib-logging-framework"/>)
cs: Místo záznamů přímo do stderr a stdout používejte framework GLib pro záznamy. (<link xref="#glib-logging-framework"/>)

note: (itstool) path: item/p
en: If systemd can be a dependency of the project, consider logging directly to the journal. (<link xref="#journald-integration"/>)
cs: Když může být projekt závislý na systemd, zvažte přímé použití záznamů v žurnálu. (<link xref="#journald-integration"/>)

note: (itstool) path: item/p
en: Do not implement log rotation and deletion; leave that to system services. (<link xref="#log-rotation"/>)
cs: Neimplementujte rotaci a mazání záznamů. Ponechte to na systémových službách. (<link xref="#log-rotation"/>)

note: (itstool) path: section/title
en: GLib Logging Framework
cs: Framework GLib pro záznamy

note: (itstool) path: section/p
en: GLib provides <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html">a logging framework</link> based around the <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log"><code>g_log()</code></link> function, with convenience wrappers <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-debug"><code>g_debug()</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-message"><code>g_message()</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-warning"><code>g_warning()</code></link> and <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-error"><code>g_error()</code></link>. The GLib logging framework has a few useful features:
cs: GLib poskytuje <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html">framework pro zaznamenávání</link>, který je postavený na funkci <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log"><code>g_log()</code></link> spolu s obalujícími funkcemi <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-debug"><code>g_debug()</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-message"><code>g_message()</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-warning"><code>g_warning()</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-error"><code>g_error()</code></link> pro větší pohodlí. Tento framework má pár užitečných vlastností:

note: (itstool) path: item/p
en: Programmatic redirection of log messages using <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log-set-handler"><code>g_log_set_handler()</code></link>.
cs: Programové přesměrování záznamu zpráv pomocí <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-log-set-handler"><code>g_log_set_handler()</code></link>.

note: (itstool) path: item/p
en: Multiple logging domains, which can be processed separately.
cs: Více domén záznamů, které mohou být zpracovány odděleně.

note: (itstool) path: item/p
en: Multiple log levels, which can be processed separately. For example, this allows debug messages to be turned on and off at runtime.
cs: Více úrovní záznamů, které mohou být zpracovány odděleně. Například to umožňuje za běhu zapnout a vypnout ladicí zprávy.

note: (itstool) path: item/p
en: Support for automatically aborting a program on ‘fatal’ messages.
cs: Podpora pro automatické přerušení programu u „kritických“ zpráv.

note: (itstool) path: section/p
en: These should be used in preference to functions like <code>printf()</code>, <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-print"><code>g_print()</code></link> and <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-printerr"><code>g_printerr()</code></link>, due to their enhanced flexibility. The logging functions allow log processing to be done in code, rather than by external shell scripting, which simplifies everything.
cs: Uvedeným postupům byste měli dát přednost před funkcemi jako jsou <code>printf()</code>, <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-print"><code>g_print()</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-printerr"><code>g_printerr()</code></link>, protože je to daleko flexibilnější. Funkce pro zaznamenávání umožňují provádět zaznamenávání přímo z kódu, namísto pomocí externích shellových skriptů, čímž se vše zjednoduší.

note: (itstool) path: section/p
en: A key reason to use the logging framework is that it is used in GLib and other related libraries already; by using it, all log messages are then going through the same system and can be processed similarly.
cs: Klíčovým důvodem pro používání frameworku pro záznamy je, že jej používá GLib a ostatní související knihovny. Když jej budete používat i vy, půjdou všechny zprávy skrz ten samý systém a mohou být zpracovány podobně.

note: (itstool) path: section/p
en: To use the GLib logging framework, define <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#G-LOG-DOMAIN:CAPS"><code>G_LOG_DOMAIN</code></link> for the project so it’s unique from all other projects. Call <code>g_debug("Message")</code> to log a debug message.
cs: Když chcete používat framework GLib pro záznamy, definujte pro projekt jedinečnou <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#G-LOG-DOMAIN:CAPS"><code>G_LOG_DOMAIN</code></link>, lišící se od ostatních projektů. Ladicí zprávu zaznamenáte zavoláním <code>g_debug("Zpráva")</code>.

note: (itstool) path: section/p
en: If the default GLib log handlers are not sufficient, for example if log messages need to be in a custom format or <link xref="#journald-integration">journald integration</link> is needed, set up a log handler with the following code:
cs: V případě, že výchozí obsluha záznamů v GLib není dostačující, například když potřebujete zaznamenávané zprávy ve vlastním formátu nebo potřebujete <link xref="#journald-integration">integraci s journald</link>, nastavte obsluhu záznamů pomocí následujícího kódu:

note: (itstool) path: section/code
en: 
    static const gchar *
    log_level_to_string (GLogLevelFlags level)
    {
      switch (level)
        {
          case G_LOG_LEVEL_ERROR: return "ERROR";
          case G_LOG_LEVEL_CRITICAL: return "CRITICAL";
          case G_LOG_LEVEL_WARNING: return "WARNING";
          case G_LOG_LEVEL_MESSAGE: return "MESSAGE";
          case G_LOG_LEVEL_INFO: return "INFO";
          case G_LOG_LEVEL_DEBUG: return "DEBUG";
          default: return "UNKNOWN";
        }
    }
    
    static void
    log_handler_cb (const gchar    *log_domain,
                    GLogLevelFlags  log_level,
                    const gchar    *message,
                    gpointer        user_data)
    {
      const gchar *log_level_str;
    
      /* Ignore debug messages if disabled. */
      if (!debug_enabled &amp;&amp; (log_level &amp; G_LOG_LEVEL_DEBUG))
        {
          return;
        }
    
      log_level_str = log_level_to_string (log_level &amp; G_LOG_LEVEL_MASK);
    
      /* Use g_printerr() for warnings and g_print() otherwise. */
      if (flags &lt;= G_LOG_LEVEL_WARNING)
        {
          g_printerr ("%s: %s: %s\n", log_domain, log_level_str, message);
        }
      else
        {
          g_print ("%s: %s: %s\n", log_domain, log_level_str, message);
        }
    }
    
    g_log_set_handler ("log-domain",
                       G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
                       log_handler_cb, NULL);
cs: 
    static const gchar *
    log_level_to_string (GLogLevelFlags level)
    {
      switch (level)
        {
          case G_LOG_LEVEL_ERROR: return "ERROR";
          case G_LOG_LEVEL_CRITICAL: return "CRITICAL";
          case G_LOG_LEVEL_WARNING: return "WARNING";
          case G_LOG_LEVEL_MESSAGE: return "MESSAGE";
          case G_LOG_LEVEL_INFO: return "INFO";
          case G_LOG_LEVEL_DEBUG: return "DEBUG";
          default: return "UNKNOWN";
        }
    }
    
    static void
    log_handler_cb (const gchar    *log_domain,
                    GLogLevelFlags  log_level,
                    const gchar    *message,
                    gpointer        user_data)
    {
      const gchar *log_level_str;
    
      /* Když je vypnuto ladění, ignorovat ladicí zprávy. */
      if (!debug_enabled &amp;&amp; (log_level &amp; G_LOG_LEVEL_DEBUG))
        {
          return;
        }
    
      log_level_str = log_level_to_string (log_level &amp; G_LOG_LEVEL_MASK);
    
      /* Použít g_printerr() pro varování a g_print() v ostatních případech. */
      if (flags &lt;= G_LOG_LEVEL_WARNING)
        {
          g_printerr ("%s: %s: %s\n", log_domain, log_level_str, message);
        }
      else
        {
          g_print ("%s: %s: %s\n", log_domain, log_level_str, message);
        }
    }
    
    g_log_set_handler ("log-domain",
                       G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
                       log_handler_cb, NULL);

note: (itstool) path: section/title
en: Exceptions
cs: Výjimky

note: (itstool) path: item/p
en: Do not use <code>g_message()</code> in normal code to print output. Printing output should be done at the top level of an application, using <code>g_print()</code>, and should be quite rare; i.e. only done in command line applications.
cs: Nepoužívejte <code>g_message()</code> v normálním kódu k výpisům. Výpisy by se měly dělat jen v nejvyšší úrovni aplikace pomocí <code>g_print()</code> a měly by být jen zřídkavé, tj. prováděné jen v aplikacích pro příkazový řádek.

note: (itstool) path: item/p
en: Do not use <code>g_warning()</code> in library code. Use <link xref="gerror"><code>GError</code>s</link> instead.
cs: Nepoužívejte <code>g_warning()</code> v programovém kódu knihoven. Místo toho použijte <link xref="gerror"><code>GError</code></link>.

note: (itstool) path: item/p
en: Similarly, do not set up log handlers in library code. Log messages should propagate through library code and be handled in a log handler at the top level of an application.
cs: Obdobně, nenastavujte obsluhu záznamů v kódu knihovny. Zprávy do záznamu by měly být propagovány z kódu knihovny ven a obslouženy v obsluze záznamu v nejvyšší úrovni aplikace.

note: (itstool) path: section/title
en: journald Integration
cs: Integrace journald

note: (itstool) path: section/p
en: Compared to conventional syslog-style logs, journald supports storage of structured logging data, which can make post-hoc analysis of logs much easier. If it’s possible to add <code>systemd-journal</code> as a dependency to a project, the project’s log handling function could be extended to use <link href="http://0pointer.de/public/systemd-man/sd_journal_send.html"><code>sd_journal_print()</code> and <code>sd_journal_send()</code></link> instead of <code>g_print()</code> and <code>g_printerr()</code>.
cs: Ve srovnání s tradičními záznamy ve stylu syslog, journald podporuje ukládání záznamů ve strukturované podobě, co usnadňuje následnou analýzu záznamů. Můžete přidat <code>systemd-journal</code> jako závislost do svého projektu a jako funkce pro obsluhu záznamů pak můžete použít <link href="http://0pointer.de/public/systemd-man/sd_journal_send.html"><code>sd_journal_print()</code> a <code>sd_journal_send()</code></link>, na místo <code>g_print()</code> a <code>g_printerr()</code>.

note: (itstool) path: section/p
en: For more information, see this <link href="http://0pointer.de/blog/projects/journal-submit.html">article on logging to the journal</link>.
cs: Další informace najdete v tomto <link href="http://0pointer.de/blog/projects/journal-submit.html">článku o záznamu do žurnálu</link>.

note: (itstool) path: section/title
en: Log Rotation
cs: Rotování záznamů

note: (itstool) path: section/p
en: Log file rotation is one feature which is out of scope of the GLib logging system. It should be handled by the normal system logging mechanisms, such as <cmd>logrotate</cmd> or <cmd>systemd-journald</cmd>.
cs: Rotování záznamů je jedna z funkcí, která jde mimo rozsah systému záznamů v GLib. Mělo by být obsluhováno normálním mechanizmem systému záznamů, jako je <cmd>logrotate</cmd> nebo <cmd>systemd-journald</cmd>.

note: (itstool) path: credit/years
en: 2014–2015
cs: 2014 – 2015

note: (itstool) path: info/desc
en: GLib main contexts, invoking functions in other threads, and the event loop
cs: Hlavní kontext GLib, vyvolání funkcí v jiných vláknech a smyčka událostí

note: (itstool) path: page/title
en: GLib Main Contexts
cs: Hlavní kontexty GLib

note: (itstool) path: item/p
en: Use <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-context-invoke-full"><code>g_main_context_invoke_full()</code></link> to invoke functions in other threads, assuming every thread has a thread default main context which runs throughout the lifetime of that thread (<link xref="#g-main-context-invoke-full"/>)
cs: K vyvolání funkcí z jiných vláknech použijte funkci <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-context-invoke-full"><code>g_main_context_invoke_full()</code></link>, která předpokládá, že každé vlákno má výchozí hlavní kontext, který běží po celou dobu existence vlákna (<link xref="#g-main-context-invoke-full"/>)

note: (itstool) path: item/p
en: Use <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> to run a function in the background without caring about the specific thread used (<link xref="#gtask"/>)
cs: Ke spuštění funkce na pozadí bez starostí o použití konkrétního vlákna použijte <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> (<link xref="#gtask"/>)

note: (itstool) path: item/p
en: Liberally use assertions to check which context executes each function, and add these assertions when first writing the code (<link xref="#checking-threading"/>)
cs: Nešetřete používáním asercí ke kontrole, který kontext spouští kterou funkci, a přidávejte tyto aserce hned při prvním psaní kódu. (<link xref="#checking-threading"/>)

note: (itstool) path: item/p
en: Explicitly document contexts a function is expected to be called in, a callback will be invoked in, or a signal will be emitted in (<link xref="#using-gmaincontext-in-a-library"/>)
cs: Výslovně zdokumentujte, ve kterém kontextu funkce očekává, že bude volána, zpětné volání vyvoláno a signál vyslán (<link xref="#using-gmaincontext-in-a-library"/>)

note: (itstool) path: item/p
en: Beware of <code>g_idle_add()</code> and similar functions which implicitly use the global-default main context (<link xref="#implicit-use-of-the-global-default-main-context"/>)
cs: Dávejte si pozor na <code>g_idle_add()</code> a podobné funkce, které implicitně používají globální výchozí hlavní kontext (<link xref="#implicit-use-of-the-global-default-main-context"/>)

note: (itstool) path: section/title
en: What is <code>GMainContext</code>?
cs: Co je to <code>GMainContext</code>?

note: (itstool) path: section/p
en: <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GMainContext"><code>GMainContext</code></link> is a generalized implementation of an <link href="https://en.wikipedia.org/wiki/Event_loop">event loop</link>, useful for implementing polled file I/O or event-based widget systems (such as GTK+). It is at the core of almost every GLib application. To understand <code>GMainContext</code> requires understanding <link href="man:poll(2)">poll()</link> and polled I/O.
cs: <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GMainContext"><code>GMainContext</code></link> je zobecněná implementace <link href="https://en.wikipedia.org/wiki/Event_loop">smyčky událostí</link>, která je vhodná pro implementaci skupinových V/V souborových operací nebo systému widgetů založeného na událostech (jako je GTK+). Je jádrem většiny aplikací GLib. Pochopení <code>GMainContext</code> vyžaduje pochopení <link href="man:poll(2)">poll()</link> a skupinových V/V.

note: (itstool) path: section/p
en: A <code>GMainContext</code> has a set of <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource"><code>GSource</code></link>s which are ‘attached’ to it, each of which can be thought of as an expected event with an associated callback function which will be invoked when that event is received; or equivalently as a set of file descriptors (FDs) to check. An event could be a timeout or data being received on a socket, for example. One iteration of the event loop will:
cs: <code>GMainContext</code> má sadu objektů <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource"><code>GSource</code></link>, které jsou k němu „připojené“. O každém z nich můžeme přemýšlet jako o očekávané události s přiřazenou funkcí zpětného volání, která bude vyvolána, když je událost přijata, nebo obdobně, jako o sadě popisovačů souborů, které se mají kontrolovat. Událostí může být například doběhnutí časovače nebo přijetí dat na soketu. Každá jednotlivá iterace smyčky události:

note: (itstool) path: item/p
en: Prepare sources, determining if any of them are ready to dispatch immediately.
cs: Připraví zdroje, přičemž určí, jestli je některý z nich připraven okamžitě vysílat.

note: (itstool) path: item/p
en: Poll the sources, blocking the current thread until an event is received for one of the sources.
cs: Seskupí zdroje a zablokuje aktuální vlákno, dokud není přijata událost pro jeden ze zdrojů.

note: (itstool) path: item/p
en: Check which of the sources received an event (several could have).
cs: Zkontroluje, který ze zdrojů přijal událost (může jich být několik).

note: (itstool) path: item/p
en: Dispatch callbacks from those sources.
cs: Vyšle zpětná volání z těchto zdrojů.

note: (itstool) path: section/p
en: This is <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#mainloop-states">explained very well</link> in the <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSourceFuncs">GLib documentation</link>.
cs: <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#mainloop-states">Velmi dobře je to vysvětlené</link> v <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSourceFuncs">dokumentaci k GLib</link>.

note: (itstool) path: section/p
en: At its core, <code>GMainContext</code> is just a <code>poll()</code> loop, with the preparation, check and dispatch stages of the loop corresponding to the normal preamble and postamble in a typical <code>poll()</code> loop implementation, such as listing 1 from <link href="http://www.linux-mag.com/id/357/">this article</link>. Typically, some complexity is needed in non-trivial <code>poll()</code>-using applications to track the lists of FDs which are being polled. Additionally, <code>GMainContext</code> adds a lot of useful functionality which vanilla <code>poll()</code> doesn’t support. Most importantly, it adds thread safety.
cs: V jádru je <code>GMainContext</code> vlastně jen smyčka <code>poll()</code> s přípravnou, kontrolní a vysílací fází smyčky odpovídající běžnému úvodu a závěru v typické implementaci smyčky <code>poll()</code>, jako je například naslouchání 1 v <link href="http://www.linux-mag.com/id/357/">tomto článku</link>. Typicky je zapotřebí jistá míra složitosti v aplikacích s netriviálním využitím <code>poll()</code> ke sledování seznamů popisovačů souborů, které nás zajímají. <code>GMainContext</code> navíc přidává spoustu užitečné funkcionality, kterou varianta <code>poll()</code> nepodporuje. Z toho nejdůležitější je bezpečné použití ve více vláknech.

note: (itstool) path: section/p
en: <code>GMainContext</code> is completely thread safe, meaning that a <code>GSource</code> can be created in one thread and attached to a <code>GMainContext</code> running in another thread. (See also: <link xref="threading"/>.) A typical use for this might be to allow worker threads to control which sockets are being listened to by a <code>GMainContext</code> in a central I/O thread. Each <code>GMainContext</code> is ‘acquired’ by a thread for each iteration it’s put through. Other threads cannot iterate a <code>GMainContext</code> without acquiring it, which guarantees that a <code>GSource</code> and its FDs will only be polled by one thread at once (since each <code>GSource</code> is attached to at most one <code>GMainContext</code>). A <code>GMainContext</code> can be swapped between threads across iterations, but this is expensive.
cs: <code>GMainContext</code> je z hlediska vláken zcela bezpečný, což znamená, že <code>GSource</code> může být vytvořen v jednom vlákně a napojen na <code>GMainContext</code> běžící v jiném vlákně. (Viz také <link xref="threading"/>). Typickým využitím je umožnit pracovnímu vláknu řídit, kterým soketům <code>GMainContext</code> naslouchá v centrálním V/V vlákně. Každý <code>GMainContext</code> je „získán“ vláknem pro každou iteraci, kterou prochází. Ostatní vlákna nemohou přes <code>GMainContext</code> iterovat bez jeho získání, což zajistí, že <code>GSource</code> a jeho popisovače souborů budou seskupeny jen jedním vláknem v každý okamžik (protože každý <code>GSource</code> je napojen nejvýše na jeden kontext <code>GMainContext</code>). <code>GMAinContext</code> může být během iterací napříč vlákny přehazován, ale je to nákladná operace.

note: (itstool) path: section/p
en: <code>GMainContext</code> is used instead of <code>poll()</code> mostly for convenience, as it transparently handles dynamically managing the array of FDs to pass to <code>poll()</code>, especially when operating over multiple threads. This is done by encapsulating FDs in <code>GSource</code>s, which decide whether those FDs should be passed to the <code>poll()</code> call on each ‘prepare’ stage of the main context iteration.
cs: <code>GMainContext</code> se používá místo <code>poll()</code> hlavně kvůli pohodlí, protože transparentně obsluhuje dynamickou správu polí s popisovači souborů předávanými do <code>poll()</code>, hlavně když se pracuje napříč více vlákny. Provádí se to zapouzdřením popisovačů polí do objektů <code>GSource</code>, které rozhodují, jestli mají být tyto popisovače souborů předány do volání <code>poll()</code> v každé „přípravné“ fázi iterace hlavního kontextu.

note: (itstool) path: section/title
en: What is <code>GMainLoop</code>?
cs: Co je to <code>GMainLoop</code>?

note: (itstool) path: section/p
en: <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GMainLoop"><code>GMainLoop</code></link> is essentially the following few lines of code, once reference counting and locking have been removed (from <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-loop-run"><code>g_main_loop_run()</code></link>):
cs: Když si odmyslíme počítání referencí a zamykání, je <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GMainLoop"><code>GMainLoop</code></link> v podstatě jen pár následujících řádků kódu (z <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-loop-run"><code>g_main_loop_run()</code></link>):

note: (itstool) path: section/p
en: Plus a fourth line in <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-loop-quit"><code>g_main_loop_quit()</code></link> which sets <code>loop-&gt;is_running = FALSE</code> and which will cause the loop to terminate once the current main context iteration ends.
cs: Plus čtyři řádky v <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-loop-quit"><code>g_main_loop_quit()</code></link>, které nastaví <code>loop-&gt;is_running = FALSE</code> a které způsobí, že se smyčka ukončí, jakmile doběhne aktuální iterace hlavního kontextu.

note: (itstool) path: section/p
en: Hence, <code>GMainLoop</code> is a convenient, thread-safe way of running a <code>GMainContext</code> to process events until a desired exit condition is met, at which point <code>g_main_loop_quit()</code> should be called. Typically, in a UI program, this will be the user clicking ‘exit’. In a socket handling program, this might be the final socket closing.
cs: Proto je <code>GMainLoop</code> vhodným, a z hlediska vláken bezpečným, způsobem, jak spustit <code>GMainContext</code>, aby zpracovával události, dokud není dosažena požadovaná výstupní podmínka. V tu chvíli by měla být zavolána funkce <code>g_main_loop_quit()</code>. V programech s uživatelským rozhraním je to typicky uživatelovo kliknutí na „Ukončit“. V programech obsluhujících sokety do může být závěrečné zavření soketu.

note: (itstool) path: section/p
en: It is important not to confuse main contexts with main loops. Main contexts do the bulk of the work: preparing source lists, waiting for events, and dispatching callbacks. A main loop simply iterates a context.
cs: Je důležité neplést si hlavní kontext s hlavní smyčkou. Hlavní kontext dělá většinu práce: připravuje seznam zdrojů, čeká na události a obesílá zpětná volání. Hlavní smyčka prostě jen opakovaně cykluje kontextem.

note: (itstool) path: section/title
en: Default Contexts
cs: Výchozí kontexty

note: (itstool) path: section/p
en: One of the important features of <code>GMainContext</code> is its support for ‘default’ contexts. There are two levels of default context: the thread-default, and the global-default. The global-default (accessed using <code>g_main_context_default()</code>) is run by GTK+ when <code>gtk_main()</code> is called. It’s also used for timeouts (<code>g_timeout_add()</code>) and idle callbacks (<code>g_idle_add()</code>) — these won’t be dispatched unless the default context is running! (See: <link xref="#implicit-use-of-the-global-default-main-context"/>.)
cs: Jednou z důležitých vlastností <code>GMainContext</code> je, že podporuje „výchozí“ kontext. Existují dvě úrovně výchozího kontextu: výchozí pro vlákno a výchozí globální. Globální (přístupný přes <code>g_main_context_default()</code>) je spuštěn GTK+ ve chvíli, kdy je zavoláno <code>gtk_main()</code>. Používá se také pro časovače (<code>g_timeout_add()</code>) a zpětná volání při nečinnosti (<code>g_idle_add()</code>) — ty nechceme obesílat, když neběží výchozí kontext! (Viz <link xref="#implicit-use-of-the-global-default-main-context"/>.)

note: (itstool) path: section/p
en: Thread-default contexts are a later addition to GLib (since version 2.22), and are generally used for I/O operations which need to run and dispatch callbacks in a thread. By calling <code>g_main_context_push_thread_default()</code> before starting an I/O operation, the thread-default context is set and the I/O operation can add its sources to that context. The context can then be run in a new main loop in an I/O thread, causing the callbacks to be dispatched on that thread’s stack rather than on the stack of the thread running the global-default main context. This allows I/O operations to be run entirely in a separate thread without explicitly passing a specific <code>GMainContext</code> pointer around everywhere.
cs: Výchozí kontexty vláken byly do GLib přidány později (od verze 2.22) a obecně se používají pro V/V operace, které potřebují spouštět a obesílat zpětná volání ve vlákně. Zavoláním <code>g_main_context_push_thread_default()</code> před spuštěním V/V operace se nastaví výchozí kontext vlákna a V/V operace může přidat své zdroje do tohoto kontextu. Kontext pak může být spuštěn v nové hlavní smyčce ve V/V vlákně, což způsobí, že zpětná volání budou obesílána v zásobníku tohoto vlákna namísto v zásobníku vlákna, ve kterém běží globální výchozí kontext. To umožňuje, aby V/V operace běžely celé v odděleném vlákně bez vyloženého předávání konkrétního ukazatele <code>GMainContext</code> všude kolem.

note: (itstool) path: section/p
en: Conversely, by starting a long-running operation with a specific thread-default context set, the calling code can guarantee that the operation’s callbacks will be emitted in that context, even if the operation itself runs in a worker thread. This is the principle behind <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link>: when a new <code>GTask</code> is created, it stores a reference to the current thread-default context, and dispatches its completion callback in that context, even if the task itself is run using <link href="https://developer.gnome.org/gio/stable/GTask.html#g-task-run-in-thread"><code>g_task_run_in_thread()</code></link>.
cs: Naopak, spuštěním dlouho trvající operace s nastaveným konkrétním výchozím kontextem vlákna, může volající kód zaručit, že zpětná volání operace budou vyslána v tomto kontextu, i když operace samotná běží v pracovním vlákně. Jde o princip stojící za <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link>: když je vytvořen nový objekt <code>GTask</code>, uloží si reference na výchozí kontext aktuálního vlákna a a vyšle jeho dokončovací zpětné volání v tomto kontextu, i když úloha samotná běží pomocí <link href="https://developer.gnome.org/gio/stable/GTask.html#g-task-run-in-thread"><code>g_task_run_in_thread()</code></link>.

note: (itstool) path: example/p
en: For example, the code below will run a <code>GTask</code> which performs two writes in parallel from a thread. The callbacks for the writes will be dispatched in the worker thread, whereas the callback from the task as a whole will be dispatched in the <code>interesting_context</code>.
cs: Například následující kód spustí <code>GTask</code>, který provede z vlákna souběžně dva zápisy. Zpětná volání pro zápisy budou obeslána v pracovním vlákně, zatímco zpětné volání z úlohy jako celku bude obesláno v <code>interesting_context</code>.

note: (itstool) path: example/code
en: 
    typedef struct {
      GMainLoop *main_loop;
      guint n_remaining;
    } WriteData;
    
    /* This is always called in the same thread as thread_cb() because
     * it’s always dispatched in the @worker_context. */
    static void
    write_cb (GObject      *source_object,
              GAsyncResult *result,
              gpointer      user_data)
    {
      WriteData *data = user_data;
      GOutputStream *stream = G_OUTPUT_STREAM (source_object);
      GError *error = NULL;
      gssize len;
    
      /* Finish the write. */
      len = g_output_stream_write_finish (stream, result, &amp;error);
      if (error != NULL)
        {
          g_error ("Error: %s", error-&gt;message);
          g_error_free (error);
        }
    
      /* Check whether all parallel operations have finished. */
      write_data-&gt;n_remaining--;
    
      if (write_data-&gt;n_remaining == 0)
        {
          g_main_loop_quit (write_data-&gt;main_loop);
        }
    }
    
    /* This is called in a new thread. */
    static void
    thread_cb (GTask        *task,
               gpointer      source_object,
               gpointer      task_data,
               GCancellable *cancellable)
    {
      /* These streams come from somewhere else in the program: */
      GOutputStream *output_stream1, *output_stream;
      GMainContext *worker_context;
      GBytes *data;
      const guint8 *buf;
      gsize len;
    
      /* Set up a worker context for the writes’ callbacks. */
      worker_context = g_main_context_new ();
      g_main_context_push_thread_default (worker_context);
    
      /* Set up the writes. */
      write_data.n_remaining = 2;
      write_data.main_loop = g_main_loop_new (worker_context, FALSE);
    
      data = g_task_get_task_data (task);
      buf = g_bytes_get_data (data, &amp;len);
    
      g_output_stream_write_async (output_stream1, buf, len,
                                   G_PRIORITY_DEFAULT, NULL, write_cb,
                                   &amp;write_data);
      g_output_stream_write_async (output_stream2, buf, len,
                                   G_PRIORITY_DEFAULT, NULL, write_cb,
                                   &amp;write_data);
    
      /* Run the main loop until both writes have finished. */
      g_main_loop_run (write_data.main_loop);
      g_task_return_boolean (task, TRUE);  /* ignore errors */
    
      g_main_loop_unref (write_data.main_loop);
    
      g_main_context_pop_thread_default (worker_context);
      g_main_context_unref (worker_context);
    }
    
    /* This can be called from any thread. Its @callback will always be
     * dispatched in the thread which currently owns
     * @interesting_context. */
    void
    parallel_writes_async (GBytes              *data,
                           GMainContext        *interesting_context,
                           GCancellable        *cancellable,
                           GAsyncReadyCallback  callback,
                           gpointer             user_data)
    {
      GTask *task;
    
      g_main_context_push_thread_default (interesting_context);
    
      task = g_task_new (NULL, cancellable, callback, user_data);
      g_task_set_task_data (task, data,
                            (GDestroyNotify) g_bytes_unref);
      g_task_run_in_thread (task, thread_cb);
      g_object_unref (task);
    
      g_main_context_pop_thread_default (interesting_context);
    }
cs: 
    typedef struct {
      GMainLoop *main_loop;
      guint n_remaining;
    } WriteData;
    
    /* Toto je voláno vždy ve stejném vlákně jako thread_cb(), protože je to
     * vždy vysláno v kontextu @worker_context. */
    static void
    write_cb (GObject      *source_object,
              GAsyncResult *result,
              gpointer      user_data)
    {
      WriteData *data = user_data;
      GOutputStream *stream = G_OUTPUT_STREAM (source_object);
      GError *error = NULL;
      gssize len;
    
      /* Dokončí zápis */
      len = g_output_stream_write_finish (stream, result, &amp;error);
      if (error != NULL)
        {
          g_error ("Error: %s", error-&gt;message);
          g_error_free (error);
        }
    
      /* Zkontroluje, jestli byly dokončeny všechny paralelní operace */
      write_data-&gt;n_remaining--;
    
      if (write_data-&gt;n_remaining == 0)
        {
          g_main_loop_quit (write_data-&gt;main_loop);
        }
    }
    
    /* Toto je voláno v novém vlákně */
    static void
    thread_cb (GTask        *task,
               gpointer      source_object,
               gpointer      task_data,
               GCancellable *cancellable)
    {
      /* Tento datový proud přichází z jiného místa v programu: */
      GOutputStream *output_stream1, *output_stream;
      GMainContext *worker_context;
      GBytes *data;
      const guint8 *buf;
      gsize len;
    
      /* Nastaví pracovní kontext pro zpětná volání zápisu */
      worker_context = g_main_context_new ();
      g_main_context_push_thread_default (worker_context);
    
      /* Nastaví zápis */
      write_data.n_remaining = 2;
      write_data.main_loop = g_main_loop_new (worker_context, FALSE);
    
      data = g_task_get_task_data (task);
      buf = g_bytes_get_data (data, &amp;len);
    
      g_output_stream_write_async (output_stream1, buf, len,
                                   G_PRIORITY_DEFAULT, NULL, write_cb,
                                   &amp;write_data);
      g_output_stream_write_async (output_stream2, buf, len,
                                   G_PRIORITY_DEFAULT, NULL, write_cb,
                                   &amp;write_data);
    
      /* Spustí hlavní smyčku, dokud nejsou dokončeny oba zápisy */
      g_main_loop_run (write_data.main_loop);
      g_task_return_boolean (task, TRUE);  /* ignore errors */
    
      g_main_loop_unref (write_data.main_loop);
    
      g_main_context_pop_thread_default (worker_context);
      g_main_context_unref (worker_context);
    }
    
    /* Toto může být voláno z kteréhokoliv vlákna. Jeho funkce @callback bude
     * vždy vyslána ve vlákně, které aktuálně vlastní @interesting_context */
    void
    parallel_writes_async (GBytes              *data,
                           GMainContext        *interesting_context,
                           GCancellable        *cancellable,
                           GAsyncReadyCallback  callback,
                           gpointer             user_data)
    {
      GTask *task;
    
      g_main_context_push_thread_default (interesting_context);
    
      task = g_task_new (NULL, cancellable, callback, user_data);
      g_task_set_task_data (task, data,
                            (GDestroyNotify) g_bytes_unref);
      g_task_run_in_thread (task, thread_cb);
      g_object_unref (task);
    
      g_main_context_pop_thread_default (interesting_context);
    }

note: (itstool) path: section/title
en: Implicit Use of the Global-Default Main Context
cs: Výchozí použití globálního výchozího hlavního kontextu

note: (itstool) path: section/p
en: Several functions implicitly add sources to the global-default main context. They should <em>not</em> be used in threaded code. Instead, use <code>g_source_attach()</code> with the <code>GSource</code> created by the replacement function from the table below.
cs: Několik funkcí přidává zdroje do globálního výchozího hlavního kontextu implicitně. Ty <em>nesmí</em> být použity v kódu vláken. Místo toho použijte <code>g_source_attach()</code> s <code>GSource</code> vytvořeným nahrazením funkce z tabulky níže.

note: (itstool) path: section/p
en: Implicit use of the global-default main context means the callback functions are invoked in the main thread, typically resulting in work being brought back from a worker thread into the main thread.
cs: Implicitní použití globálního výchozího hlavního kontextu znamená, že jsou funkce zpětného volání vyvolány v hlavním vlákně, typicky jako výsledek práce práce přenesené zpět z pracovního vlákna do hlavního vlákna.

note: (itstool) path: td/p
en: Do not use
cs: Nepoužívat

note: (itstool) path: td/p
en: Use instead
cs: Místo toho použít

note: (itstool) path: example/p
en: So to delay some computation in a worker thread, use the following code:
cs: Takže prodlevu v nějakém výpočtu v pracovním vlákně uděláte pomocí následujícího kódu:

note: (itstool) path: example/code
en: 
    static guint
    schedule_computation (guint delay_seconds)
    {
      GSource *source = NULL;
      GMainContext *context;
      guint id;
    
      /* Get the calling context. */
      context = g_main_context_get_thread_default ();
    
      source = g_timeout_source_new_seconds (delay_seconds);
      g_source_set_callback (source, do_computation, NULL, NULL);
      id = g_source_attach (source, context);
      g_source_unref (source);
    
      /* The ID can be used with the same @context to
       * cancel the scheduled computation if needed. */
      return id;
    }
    
    static void
    do_computation (gpointer user_data)
    {
      /* … */
    }
cs: 
    static guint
    schedule_computation (guint delay_seconds)
    {
      GSource *source = NULL;
      GMainContext *context;
      guint id;
    
      /* Získat kontext volání. */
      context = g_main_context_get_thread_default ();
    
      source = g_timeout_source_new_seconds (delay_seconds);
      g_source_set_callback (source, do_computation, NULL, NULL);
      id = g_source_attach (source, context);
      g_source_unref (source);
    
      /* Když je potřeba, může být ID použito se stejným 
       * @context ke zrušení naplánovaného výpočtu. */
      return id;
    }
    
    static void
    do_computation (gpointer user_data)
    {
      /* … */
    }

note: (itstool) path: section/title
en: Using <code>GMainContext</code> in a Library
cs: Použití <code>GMainContext</code> v knihovně

note: (itstool) path: section/p
en: At a high level, library code must not make changes to main contexts which could affect the execution of an application using the library, for example by changing when the application’s <code>GSource</code>s are dispatched. There are various best practices which can be followed to aid this.
cs: Na nejvyšší úrovni kód knihovny nesmí provádět změny v hlavním kontextu, který by mohly ovlivnit provádění aplikace, která používá knihovnu. Například změnou, když je vyslán <code>GSource</code> patřící aplikaci. Existuje řada správných zvyklostí, kterých je dobré se držet, aby tomu tak bylo.

note: (itstool) path: section/p
en: Never iterate a context created outside the library, including the global-default or thread-default contexts. Otherwise, <code>GSource</code>s created in the application may be dispatched when the application is not expecting it, causing <link href="https://en.wikipedia.org/wiki/Reentrancy_%28computing%29">re-entrancy problems</link> for the application code.
cs: Nikdy neprovádějte iteraci kontextu vytvořeného mimo knihovnu. Týká se to i výchozího globálního kontextu a výchozího kontextu vlákna. V opačném případě může být <code>GSource</code> vytvořený v aplikaci vyslán, když to aplikace neočekává, což způsobí <link href="https://en.wikipedia.org/wiki/Reentrancy_%28computing%29">problém s opětovným vstupem (reentrance)</link> v kódu aplikace.

note: (itstool) path: section/p
en: Always remove <code>GSource</code>s from a main context before dropping the library’s last reference to the context, especially if it may have been exposed to the application (for example, as a thread-default). Otherwise the application may keep a reference to the main context and continue iterating it after the library has returned, potentially causing unexpected source dispatches in the library. This is equivalent to not assuming that dropping the library’s last reference to a main context will finalize that context.
cs: Před zahozením poslední reference z knihovny na kontext vždy odstraňte z hlavního kontextu zdroje <code>GSource</code>, především když mohou být vystaveny aplikaci (například jako výchozí vlákno). V opačném případě může aplikace zachovat referenci na hlavní kontext a pokračovat s jeho iteracemi po návratu z knihovny, což případně může způsobit nechtěné vysílání zdroje v knihovně. Je to to stejné, jako když nepředpokládáte, že zahození poslední reference z knihovny na hlavní kontext tento kontext finalizuje.

note: (itstool) path: section/p
en: If the library is designed to be used from multiple threads, or in a context-aware fashion, always document which context each callback will be dispatched in. For example, “callbacks will always be dispatched in the context which is the thread-default at the time of the object’s construction”. Developers using the library’s API need to know this information.
cs: Pokud je knihovna navržena pro použití z více vláken nebo ve stylu kontextů, zdokumentujte vždy, ve kterém kontextu budou jednotlivá zpětná volání vysílána. Například „callbacks will always be dispatched in the context which is the thread-default at the time of the object’s construction“ (zpětná volání budou v době vytváření objektu vždy vyslána v kontextu, který je pro vlákno výchozí). Vývojáři používající API knihovny tuto informaci potřebují.

note: (itstool) path: section/p
en: Use <code>g_main_context_invoke()</code> to ensure callbacks are dispatched in the right context. It’s much easier than manually using <code>g_idle_source_new()</code> to transfer work between contexts. (See: <link xref="#ensuring-functions-are-called-in-the-right-context"/>.)
cs: Používejte <code>g_main_context_invoke()</code>, abyste zajistili, že zpětné volání bude vysláno ve správném kontextu. Je to mnohem jednodušší, než ruční použití <code>g_idle_source_new()</code> k přenosu práce mezi kontexty. (Viz <link xref="#ensuring-functions-are-called-in-the-right-context"/>.)

note: (itstool) path: section/p
en: Libraries should never use <code>g_main_context_default()</code> (or, equivalently, pass <code>NULL</code> to a <code>GMainContext</code>-typed parameter). Always store and explicitly use a specific <code>GMainContext</code>, even if it often points to some default context. This makes the code easier to split out into threads in future, if needed, without causing hard-to-debug problems caused by callbacks being invoked in the wrong context.
cs: Knihovny by nikdy neměly použít <code>g_main_context_default()</code> (nebo udělat to stejné předáním <code>NULL</code> do parametru typu <code>GMainContext</code>). Vždy uložte a výslovně použijte konkrétní <code>GMainContext</code>, i když často ukazuje na nějaký výchozí kontext. V případě potřeby to v budoucnu usnadní rozdělení kódu do vláken, aniž by to způsobilo těžko laditelné probléme vznikající zpětnými voláními vyvolanými v nesprávném kontextu.

note: (itstool) path: section/p
en: <link xref="async-programming">Write things asynchronously</link> internally (using <link xref="#gtask"><code>GTask</code></link> where appropriate), and keep synchronous wrappers at the very top level of an API, where they can be implemented by calling <code>g_main_context_iteration()</code> on a specific <code>GMainContext</code>. Again, this makes future refactoring easier. This is demonstrated in the above example: the thread uses <code>g_output_stream_write_async()</code> rather than <code>g_output_stream_write()</code>. A worker thread may be used instead, and this can simplify the callback chain for long series of asynchronous calls; but at the cost of increased complexity in verifying the code is race-free.
cs: Věci interně <link xref="async-programming">pište jako asynchronní</link> (kde je to vhodné, tak pomocí <link xref="#gtask"><code>GTask</code></link>) a na nejvyšší úrovni API pak udržujte synchronní obalující funkci, kterou můžete implementovat pomocí volání <code>g_main_context_iteration()</code> na příslušný <code>GMainContext</code>. Pro zopakování: umožní to v budoucnu snadnější přepracování kódu. Ukázáno je to na příkladu výše: vlákno používá raději <code>g_output_stream_write_async()</code> namísto <code>g_output_stream_write()</code>. Místo toho může být použito pracovní vlákno a tím se může zjednodušit řetěz zpětných volání pro dlouhé posloupnosti asynchronních volání, ale za cenu nárustu složitosti ověřování kódu vůči souběhu podmínek.

note: (itstool) path: section/p
en: Always match pushes and pops of the thread-default main context: <code>g_main_context_push_thread_default()</code> and <code>g_main_context_pop_thread_default()</code>.
cs: Vždy si musí odpovídat počet vložení a vyjmutí výchozího hlavního kontextu vlákna: <code>g_main_context_push_thread_default()</code> a <code>g_main_context_pop_thread_default()</code>.

note: (itstool) path: section/title
en: Ensuring Functions are Called in the Right Context
cs: Zajištění, aby funkce byly volány ve správném kontextu

note: (itstool) path: section/p
en: The ‘right context’ is the thread-default main context of the <em>thread the function should be executing in</em>. This assumes the typical case that every thread has a <em>single</em> main context running in a main loop. A main context effectively provides a work or <link href="https://en.wikipedia.org/wiki/Message_queue">message queue</link> for the thread — something which the thread can periodically check to determine if there is work pending from another thread. Putting a message on this queue – invoking a function in another main context – will result in it eventually being dispatched in that thread.
cs: „Ten pravý kontext“ je výchozí hlavní kontext vlákna pro <em>vlákno, ve kterém má být funkce spuštěna</em>. Předpokládá to typický případ, kdy každé vlákno má <em>jeden</em> hlavní kontext, ve kterém běží hlavní smyčka. Hlavní kontext v podstatě poskytuje práci nebo <link href="https://en.wikipedia.org/wiki/Message_queue">frontu zpráv</link> pro vlákno – něco, v čem vlákno může pravidelně kontrolovat, jestli byla dokončena práce v jiném vlákně. Vložením zprávy do fronty – vyvoláním funkce v jiném hlavním kontextu – způsobí její případné vyslání v onom vlákně.

note: (itstool) path: example/p
en: For example, if an application does a long and CPU-intensive computation it should schedule this in a background thread so that UI updates in the main thread are not blocked. The results of the computation, however, might need to be displayed in the UI, so some UI update function must be called in the main thread once the computation’s complete.
cs: Například, když aplikace provádí nějaké dlouhé a na výkon procesoru náročné výpočty, měla by je naplánovat ve vlákně na pozadí, aby se neblokovaly aktualizace uživatelského rozhraní v hlavním vlákně. Může ale být zapotřebí výsledky výpočtu zobrazit v uživatelském rozhraní, takže funkce, která to bude mít na starosti, musí být po dokončení výpočtu zavolána v hlavním vlákně.

note: (itstool) path: example/p
en: Furthermore, if the computation function can be limited to a single thread, it becomes easy to eliminate the need for locking a lot of the data it accesses. This assumes that other threads are implemented similarly and hence most data is only accessed by a single thread, with threads communicating by <link href="https://en.wikipedia.org/wiki/Message_passing">message passing</link>. This allows each thread to update its data at its leisure, which significantly simplifies locking.
cs: Mimo to může být výpočetní funkce omezena jen na jedno vlákno, aby se usnadnilo zamezení potřeby zamykat příliš dat při přístupu k nim. To předpokládá, že ostatní vlákna jsou implementována podobně a tudíž je k většině dat přistupováno jen z jediného vlákna a mezi vlákny se komunikuje pomocí <link href="https://cs.wikipedia.org/wiki/Zas%C3%ADl%C3%A1n%C3%AD_zpr%C3%A1v">předávání zpráv</link>. Umožní to jednotlivým vláknům aktualizovat svá data, kdy se jim to hodí, což významně zjednodušuje zamykání.

note: (itstool) path: section/p
en: For some functions, there might be no reason to care which context they’re executed in, perhaps because they’re asynchronous and hence do not block the context. However, it is still advisable to be explicit about which context is used, since those functions may emit signals or invoke callbacks, and for reasons of thread safety it’s necessary to know which threads those signal handlers or callbacks are going to be invoked in.
cs: U některých funkcí nemusí být žádný důvod se starat o to, ve kterém kontextu jsou spuštěné, protože jsou asynchronní a tudíž kontext neblokují. I přesto je rozumné vědět o tom, který kontext je použit, protože tyto funkce mohou vysílat signály nebo vyvolávat zpětná volání a z důvodu bezpečnosti vlákna je nutné vědět, která vlákna hodlají tyto obsluhy signálů nebo zpětná volání vyvolat.

note: (itstool) path: example/p
en: For example, the progress callback in <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-copy-async"><code>g_file_copy_async()</code></link> is documented as being called in the thread-default main context at the time of the initial call.
cs: Například pro průběh volání v <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-copy-async"><code>g_file_copy_async()</code></link> je zdokumentováno, že se volá ve výchozím vlákně hlavního kontextu v době volání inicializace.

note: (itstool) path: section/title
en: Principles of Invocation
cs: Principy vyvolání

note: (itstool) path: section/p
en: The core principle of invoking a function in a specific context is simple, and is walked through below to explain the concepts. In practice the <link xref="#g-main-context-invoke-full">convenience method, <code>g_main_context_invoke_full()</code></link> should be used instead.
cs: Klíčový princip vyvolání funkce v konkrétním kontextu je jednoduchý a je probrán níže ve vysvětlení konceptu. V praxi by se místo toho měla použít <link xref="#g-main-context-invoke-full">vhodná metoda <code>g_main_context_invoke_full()</code></link>.

note: (itstool) path: section/p
en: A <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource"><code>GSource</code></link> has to be added to the target <code>GMainContext</code>, which will invoke the function when it’s dispatched. This <code>GSource</code> should almost always be an idle source created with <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-idle-source-new"><code>g_idle_source_new()</code></link>, but this doesn’t have to be the case. It could be a timeout source so that the function is executed after a delay, for example.
cs: Do cílového <code>GMainContext</code>, který vyvolá funkci, když je obeslán, musí být přidán <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource"><code>GSource</code></link>. Tento <code>GSource</code> by většinou měl být zdroj pro nečinnost vytvořený pomocí <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-idle-source-new"><code>g_idle_source_new()</code></link>, ale nemusí tomu tak být nutně. Může jít například i o zdroj časovače, takže ona funkce bude spuštěna po nějaké prodlevě.

note: (itstool) path: section/p
en: The <code>GSource</code> will be <link xref="#what-is-gmaincontext">dispatched as soon as it’s ready</link>, calling the function on the thread’s stack. In the case of an idle source, this will be as soon as all sources at a higher priority have been dispatched — this can be tweaked using the idle source’s priority parameter with <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-set-priority"><code>g_source_set_priority()</code></link>. The source will typically then be destroyed so the function is only executed once (though again, this doesn’t have to be the case).
cs: <code>GSource</code> bude <link xref="#what-is-gmaincontext">vyslán hned, jak bude připraven</link>, zavoláním funkce na zásobníku vlákna. V případě nečinnosti zdroje to bude hned, jak budou vyslány zdroje s vyšší prioritou – to lze vyladit pomocí parametru s prioritou zdroje v <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-set-priority"><code>g_source_set_priority()</code></link>. Typicky je zdroj následně zlikvidován, takže funkce se spustí jen jednou (a když znovu, tak to nemusí být ta samá situace).

note: (itstool) path: section/p
en: Data can be passed between threads as the <code>user_data</code> passed to the <code>GSource</code>’s callback. This is set on the source using <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-set-callback"><code>g_source_set_callback()</code></link>, along with the callback function to invoke. Only a single pointer is provided, so if multiple data fields need passing, they must be wrapped in an allocated structure.
cs: Data mezi vlákny mohou být předávána jako <code>user_data</code> předaná do zpětného volání patřícího <code>GSource</code>. Nastaví se to na zdroji pomocí <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-set-callback"><code>g_source_set_callback()</code></link> společně s funkcí zpětného volání, která má být vyvolána. K dispozici je jen jeden ukazatel, takže když potřebujete předat více polí, musíte je zabalit do nějaké struktury, kterou si naalokujete.

note: (itstool) path: example/p
en: The example below demonstrates the underlying principles, but there are convenience methods explained below which simplify things.
cs: Následující příklad demonstruje základní principy, ale existují vhodné metody probrané dále, které vše zjednodušují.

note: (itstool) path: example/code
en: 
    /* Main function for the background thread, thread1. */
    static gpointer
    thread1_main (gpointer user_data)
    {
      GMainContext *thread1_main_context = user_data;
      GMainLoop *main_loop;
    
      /* Set up the thread’s context and run it forever. */
      g_main_context_push_thread_default (thread1_main_context);
    
      main_loop = g_main_loop_new (thread1_main_context, FALSE);
      g_main_loop_run (main_loop);
      g_main_loop_unref (main_loop);
    
      g_main_context_pop_thread_default (thread1_main_context);
      g_main_context_unref (thread1_main_context);
    
      return NULL;
    }
    
    /* A data closure structure to carry multiple variables between
     * threads. */
    typedef struct {
      gchar   *some_string;  /* owned */
      guint    some_int;
      GObject *some_object;  /* owned */
    } MyFuncData;
    
    static void
    my_func_data_free (MyFuncData *data)
    {
      g_free (data-&gt;some_string);
      g_clear_object (&amp;data-&gt;some_object);
      g_free (data);
    }
    
    static void
    my_func (const gchar *some_string,
             guint        some_int,
             GObject     *some_object)
    {
      /* Do something long and CPU intensive! */
    }
    
    /* Convert an idle callback into a call to my_func(). */
    static gboolean
    my_func_idle (gpointer user_data)
    {
      MyFuncData *data = user_data;
    
      my_func (data-&gt;some_string, data-&gt;some_int, data-&gt;some_object);
    
      return G_SOURCE_REMOVE;
    }
    
    /* Function to be called in the main thread to schedule a call to
     * my_func() in thread1, passing the given parameters along. */
    static void
    invoke_my_func (GMainContext *thread1_main_context,
                    const gchar  *some_string,
                    guint         some_int,
                    GObject      *some_object)
    {
      GSource *idle_source;
      MyFuncData *data;
    
      /* Create a data closure to pass all the desired variables
       * between threads. */
      data = g_new0 (MyFuncData, 1);
      data-&gt;some_string = g_strdup (some_string);
      data-&gt;some_int = some_int;
      data-&gt;some_object = g_object_ref (some_object);
    
      /* Create a new idle source, set my_func() as the callback with
       * some data to be passed between threads, bump up the priority
       * and schedule it by attaching it to thread1’s context. */
      idle_source = g_idle_source_new ();
      g_source_set_callback (idle_source, my_func_idle, data,
                             (GDestroyNotify) my_func_data_free);
      g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
      g_source_attach (idle_source, thread1_main_context);
      g_source_unref (idle_source);
    }
    
    /* Main function for the main thread. */
    static void
    main (void)
    {
      GThread *thread1;
      GMainContext *thread1_main_context;
    
      /* Spawn a background thread and pass it a reference to its
       * GMainContext. Retain a reference for use in this thread
       * too. */
      thread1_main_context = g_main_context_new ();
      g_thread_new ("thread1", thread1_main,
                    g_main_context_ref (thread1_main_context));
    
      /* Maybe set up your UI here, for example. */
    
      /* Invoke my_func() in the other thread. */
      invoke_my_func (thread1_main_context,
                      "some data which needs passing between threads",
                      123456, some_object);
    
      /* Continue doing other work. */
    }
cs: 
    /* Hlavní funkce pro vlákno na pozadí thread1 */
    static gpointer
    thread1_main (gpointer user_data)
    {
      GMainContext *thread1_main_context = user_data;
      GMainLoop *main_loop;
    
      /* Nastaví kontext vlákna a navždy jej spustí */
      g_main_context_push_thread_default (thread1_main_context);
    
      main_loop = g_main_loop_new (thread1_main_context, FALSE);
      g_main_loop_run (main_loop);
      g_main_loop_unref (main_loop);
    
      g_main_context_pop_thread_default (thread1_main_context);
      g_main_context_unref (thread1_main_context);
    
      return NULL;
    }
    
    /* Zapouzdření dat pro obsluhu více proměnných mezi vlákny */
    typedef struct {
      gchar   *some_string;  /* owned */
      guint    some_int;
      GObject *some_object;  /* owned */
    } MyFuncData;
    
    static void
    my_func_data_free (MyFuncData *data)
    {
      g_free (data-&gt;some_string);
      g_clear_object (&amp;data-&gt;some_object);
      g_free (data);
    }
    
    static void
    my_func (const gchar *some_string,
             guint        some_int,
             GObject     *some_object)
    {
      /* Zde se dělá něco náročného na čas a procesor! */
    }
    
    /* Převede zpětné volání nečinnosti na volání my_func() */
    static gboolean
    my_func_idle (gpointer user_data)
    {
      MyFuncData *data = user_data;
    
      my_func (data-&gt;some_string, data-&gt;some_int, data-&gt;some_object);
    
      return G_SOURCE_REMOVE;
    }
    
    /* Funkce, která má být volána v hlavním vlákně, aby plánovala volání
     * my_func() ve vlákně thread1 a přitom předala zadané parametry */
    static void
    invoke_my_func (GMainContext *thread1_main_context,
                    const gchar  *some_string,
                    guint         some_int,
                    GObject      *some_object)
    {
      GSource *idle_source;
      MyFuncData *data;
    
      /* Vytvoří zapouzdření dat pro předání všech požadovaných proměnných
       * mezi vlákny */
      data = g_new0 (MyFuncData, 1);
      data-&gt;some_string = g_strdup (some_string);
      data-&gt;some_int = some_int;
      data-&gt;some_object = g_object_ref (some_object);
    
      /* Vytvoří nový zdroj nečinnosti, nastaví my_func() jako zpětné volání
       * s nějakými daty, která budou předána mezi vlákny, zvýší prioritu a
       * a naplánuje ji napojením na kontext vlákna thread1 */
      idle_source = g_idle_source_new ();
      g_source_set_callback (idle_source, my_func_idle, data,
                             (GDestroyNotify) my_func_data_free);
      g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
      g_source_attach (idle_source, thread1_main_context);
      g_source_unref (idle_source);
    }
    
    /* Hlavní funkce pro hlavní vlákno */
    static void
    main (void)
    {
      GThread *thread1;
      GMainContext *thread1_main_context;
    
      /* Spawn a background thread and pass it a reference to its
       * GMainContext. Retain a reference for use in this thread
       * too. */
      thread1_main_context = g_main_context_new ();
      g_thread_new ("thread1", thread1_main,
                    g_main_context_ref (thread1_main_context));
    
      /* Zde je možné například nastavit uživatelské rozhraní */
    
      /* Vyvolá my_func() v jiném vlákně */
      invoke_my_func (thread1_main_context,
                      "some data which needs passing between threads",
                      123456, some_object);
    
      /* Zde se pokračuje v jiné práci */
    }

note: (itstool) path: example/p
en: This invocation is <em style="strong">uni-directional</em>: it calls <code>my_func()</code> in <code>thread1</code>, but there’s no way to return a value to the main thread. To do that, the same principle needs to be used again, invoking a callback function in the main thread. It’s a straightforward extension which isn’t covered here.
cs: Toto vyvolání je <em style="strong">jednosměrné</em>: zavolá se <code>my_func()</code> v <code>thread1</code>, ale neexistuje žádný způsob, jak vrátit hodnotu do hlavního vlákna. Když to potřebujete udělat, je potřeba znovu použít ten samý princip, tj. vyvolat funkci zpětného volání v hlavním vlákně. Jedná se o přímočaré rozšíření, které zde není potřeba rozebírat.

note: (itstool) path: example/p
en: To maintain thread safety, data which is potentially accessed by multiple threads must make those accesses mutually exclusive using a <link href="https://en.wikipedia.org/wiki/Mutual_exclusion">mutex</link>. Data potentially accessed by multiple threads: <code>thread1_main_context</code>, passed in the fork call to <code>thread1_main</code>; and <code>some_object</code>, a reference to which is passed in the data closure. Critically, GLib guarantees that <code>GMainContext</code> is thread safe, so sharing <code>thread1_main_context</code> between threads is safe. The example assumes that other code accessing <code>some_object</code> is thread safe.
cs: Aby byla zachována bezpečnost vlákna, musí být přístup k datům, ke kterým je potenciálně možné přistupovat z více vláken, vzájemně vyloučen pomocí <link href="https://cs.wikipedia.org/wiki/Vz%C3%A1jemn%C3%A9_vylou%C4%8Den%C3%AD">mutexu</link>. Data s potenciálním přístupem z více vláken: <code>thread1_main_context</code>, předaný při rozvětvení do <code>thread1_main</code>, a <code>some_object</code>, reference, do které jsou předána zapouzdřená data. Podstatné je, že GLib zaručuje, že <code>GMainContext</code> je z hlediska vláken bezpečný, takže sdílení <code>thread1_main_context</code> mezi vlákny je bezpečné. Příklad předpokládá, že ostatní kód přistupující k <code>some_object</code> je z hlediska vláken bezpečný.

note: (itstool) path: example/p
en: Note that <code>some_string</code> and <code>some_int</code> cannot be accessed from both threads, because <em>copies</em> of them are passed to <code>thread1</code>, rather than the originals. This is a standard technique for making cross-thread calls thread safe without requiring locking. It also avoids the problem of synchronizing freeing <code>some_string</code>.
cs: Všimněte si, že k proměnným <code>some_string</code> a <code>some_int</code> nelze přistupovat z obou vláken, protože do vlákna <code>thread1</code> jsou místo originálů předávány jejich <code>kopie</code>. Jedná se o standardní techniku používanou z důvodu, aby křížové volání vláken bylo z hlediska vícevláknového zpracování bezpečné, aniž by bylo nutné zamykání. Také se tím předejte problémům se synchronizací při uvolňování <code>some_string</code>.

note: (itstool) path: example/p
en: Similarly, a reference to <code>some_object</code> is transferred to <code>thread1</code>, which works around the issue of synchronizing destruction of the object (see <link xref="memory-management"/>).
cs: A obdobně, reference na <code>some_object</code> je přenášena do vlákna <code>thread1</code>, které řeší problém se synchronizací při likvidaci objektu (viz <link xref="memory-management"/>).

note: (itstool) path: example/p
en: <code>g_idle_source_new()</code> is used rather than the simpler <code>g_idle_add()</code> so the <code>GMainContext</code> to attach to can be specified.
cs: Namísto jednodušší <code>g_idle_add()</code> je požita raději funkce <code>g_idle_source_new()</code>, takže lze určit připojený <code>GMainContext</code>.

note: (itstool) path: section/title
en: Convenience Method: <code>g_main_context_invoke_full()</code>
cs: Užitečná metoda: <code>g_main_context_invoke_full()</code>

note: (itstool) path: section/p
en: This is simplified greatly by the convenience method, <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-context-invoke-full"><code>g_main_context_invoke_full()</code></link>. It invokes a callback so that the specified <code>GMainContext</code> is owned during the invocation. Owning a main context is almost always equivalent to running it, and hence the function is invoked in the thread for which the specified context is the thread-default.
cs: To vše se dá úžasně zjednodušit správnou metodou <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-main-context-invoke-full"><code>g_main_context_invoke_full()</code></link>. Ta vyvolá zpětné volání tak, že <code>GMainContext</code> je během něj vlastněn. Vlastnění hlavního kontextu je téměř vždy to stejné, jako jej spustit, a tím pádem je funkce vyvolána ve vlákně, pro které je určený kontext výchozí.

note: (itstool) path: section/p
en: <code>g_main_context_invoke()</code> can be used instead if the user data does not need to be freed by a <code>GDestroyNotify</code> callback after the invocation returns.
cs: V případě, že uživatelská data není nutné po návratu z volání uvolňovat pomocí zpětného volání <code>GDestroyNotify</code>, dá se místo toho použít funkce <code>g_main_context_invoke()</code>.

note: (itstool) path: example/p
en: Modifying the earlier example, the <code>invoke_my_func()</code> function can be replaced by the following:
cs: Upravený předchozí příklad – funkce <code>invoke_my_func()</code> může být nahrazena následovně:

note: (itstool) path: example/code
en: 
    static void
    invoke_my_func (GMainContext *thread1_main_context,
                    const gchar  *some_string,
                    guint         some_int,
                    GObject      *some_object)
    {
      MyFuncData *data;
    
      /* Create a data closure to pass all the desired variables
       * between threads. */
      data = g_new0 (MyFuncData, 1);
      data-&gt;some_string = g_strdup (some_string);
      data-&gt;some_int = some_int;
      data-&gt;some_object = g_object_ref (some_object);
    
      /* Invoke the function. */
      g_main_context_invoke_full (thread1_main_context,
                                  G_PRIORITY_DEFAULT, my_func_idle,
                                  data,
                                  (GDestroyNotify) my_func_data_free);
    }
cs: 
    static void
    invoke_my_func (GMainContext *thread1_main_context,
                    const gchar  *some_string,
                    guint         some_int,
                    GObject      *some_object)
    {
      MyFuncData *data;
    
      /* Vytvoří zapouzdření dat pro předávání všech požadovaných proměnných
       * mezi vlákny */
      data = g_new0 (MyFuncData, 1);
      data-&gt;some_string = g_strdup (some_string);
      data-&gt;some_int = some_int;
      data-&gt;some_object = g_object_ref (some_object);
    
      /* Vyvolá funkci */
      g_main_context_invoke_full (thread1_main_context,
                                  G_PRIORITY_DEFAULT, my_func_idle,
                                  data,
                                  (GDestroyNotify) my_func_data_free);
    }

note: (itstool) path: example/p
en: Consider what happens if <code>invoke_my_func()</code> were called from <code>thread1</code>, rather than from the main thread. With the original implementation, the idle source would be added to <code>thread1</code>’s context and dispatched on the context’s next iteration (assuming no pending dispatches with higher priorities). With the improved implementation, <code>g_main_context_invoke_full()</code> will notice that the specified context is already owned by the thread (or ownership can be acquired by it), and will call <code>my_func_idle()</code> directly, rather than attaching a source to the context and delaying the invocation to the next context iteration.
cs: Zamysleme se, co se stane, kdy je <code>invoke_my_func()</code> zavolána z <code>thread1</code>, místo z hlavního vlákna. V původní implementaci by byl nečinný zdroj přidán do kontextu vlákna <code>thread1</code> a vyslán v následující iteraci kontextu (předpokládáme, že nečeká vyslání s vyšší prioritou). Ve vylepšené implementaci si <code>g_main_context_invoke_full()</code> všimne, že uvedený kontext je již vlastněn vláknem (nebo jeho vlastnictví může získat), a zavolá přímo <code>my_func_idle()</code>, namísto aby zdroj připojovala ke kontextu a čekala na vyvolání následující iterace.

note: (itstool) path: example/p
en: This subtle behavior difference doesn’t matter in most cases, but is worth bearing in mind since it can affect blocking behavior (<code>invoke_my_func()</code> would go from taking negligible time, to taking the same amount of time as <code>my_func()</code> before returning).
cs: Na tomto jemném rozdílu v chování většinou nesejde, ale je dobré na něj pamatovat, protože může ovlivnit chování při blokování (<code>invoke_my_func()</code> by zabrala nezanedbatelné množství času, které by odpovídalo stejnému množství času jako u <code>my_func()</code> před návratem).

note: (itstool) path: section/title
en: Checking Threading
cs: Kontrola vláken

note: (itstool) path: section/p
en: It is useful to document which thread each function should be called in, in the form of an assertion:
cs: Je vhodné zdokumentovat, která funkce je volána ve kterém vlákně, a to formou aserce:

note: (itstool) path: section/p
en: If that’s put at the top of each function, any assertion failure will highlight a case where a function has been called from the wrong thread. It is much easier to write these assertions when initially developing code, rather than debugging race conditions which can easily result from a function being called in the wrong thread.
cs: Když tohle vložíte na začátek každé funkce, selhání aserce zviditelní ty případy, kdy je funkce volána z nesprávného vlákna. Je mnohem jednodušší napsat tyto aserce v rané fázi vývoje kódu, než pak ladit souběh podmínek, který může při volání funkce z nesprávného vlákna snadno nastat.

note: (itstool) path: section/p
en: This technique can also be applied to signal emissions and callbacks, improving type safety as well as asserting the right context is used. Note that signal emission via <link href="https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-emit"><code>g_signal_emit()</code></link> is synchronous, and doesn’t involve a main context at all.
cs: Tuto techniku lze použít i u vysílání signálů a zpětných volání, díky čemuž se zvýší typová bezpečnost i kontrola, jestli je použit správný kontext. Upozorňujeme, že vyslání signálu přes <link href="https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-emit"><code>g_signal_emit()</code></link> je asynchronní a vůbec se netýká hlavního kontextu.

note: (itstool) path: example/p
en: For example, instead of using the following when emitting a signal:
cs: Například místo použití následujícího kódu při vyslání signálu:

note: (itstool) path: example/code
en: 
    guint param1;  /* arbitrary example parameters */
    gchar *param2;
    guint retval = 0;
    
    g_signal_emit_by_name (my_object, "some-signal",
                           param1, param2, &amp;retval);
cs: 
    guint param1;  /* příklad libovolného parametru */
    gchar *param2;
    guint retval = 0;
    
    g_signal_emit_by_name (my_object, "some-signal",
                           param1, param2, &amp;retval);

note: (itstool) path: example/p
en: The following can be used:
cs: Může být použito následující:

note: (itstool) path: section/p
en: <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> provides a slightly different approach to invoking functions in other threads, which is more suited to the case where a function should be executed in <em>some</em> background thread, but not a specific one.
cs: <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> poskytuje k vyvolání funkcí v jiných vláknech trochu odlišný přístup, který je zaměřen více na případy, kdy by funkce měla být spuštěna v <em>nějakém</em> vlákně na pozadí, ale není určeno, v kterém konkrétním.

note: (itstool) path: section/p
en: <code>GTask</code> takes a data closure and a function to execute, and provides ways to return the result from this function. It handles everything necessary to run that function in an arbitrary thread belonging to some thread pool internal to GLib.
cs: <code>GTask</code> přebírá zapouzdřená data a funkci ke spuštění a poskytuje způsob, jak vrátit výsledky z této funkce. Postará se o vše potřebné ke spuštění funkce v libovolném vlákně náležejícímu do stejného svazku vláken sdílených interně v GLib.

note: (itstool) path: example/p
en: By combining <link xref="#g-main-context-invoke-full"><code>g_main_context_invoke_full()</code></link> and <code>GTask</code>, it is possible to run a task in a specific context and effortlessly return its result to the current context:
cs: Zkombinováním <link xref="#g-main-context-invoke-full"><code>g_main_context_invoke_full()</code></link> a <code>GTask</code> je možné spustit úlohu v konkrétním kontextu a bez většího úsilí vrátit její výsledek do aktuálního kontextu:

note: (itstool) path: example/code
en: 
    /* This will be invoked in thread1. */
    static gboolean
    my_func_idle (gpointer user_data)
    {
      GTask *task = G_TASK (user_data);
      MyFuncData *data;
      gboolean retval;
    
      /* Call my_func() and propagate its returned boolean to
       * the main thread. */
      data = g_task_get_task_data (task);
      retval = my_func (data-&gt;some_string, data-&gt;some_int,
                        data-&gt;some_object);
      g_task_return_boolean (task, retval);
    
      return G_SOURCE_REMOVE;
    }
    
    /* Whichever thread this is invoked in, the @callback will be
     * invoked in, once my_func() has finished and returned a result. */
    static void
    invoke_my_func_with_result (GMainContext        *thread1_main_context,
                                const gchar         *some_string,
                                guint                some_int,
                                GObject             *some_object,
                                GAsyncReadyCallback  callback,
                                gpointer             user_data)
    {
      MyFuncData *data;
    
      /* Create a data closure to pass all the desired variables
       * between threads. */
      data = g_new0 (MyFuncData, 1);
      data-&gt;some_string = g_strdup (some_string);
      data-&gt;some_int = some_int;
      data-&gt;some_object = g_object_ref (some_object);
    
      /* Create a GTask to handle returning the result to the current
       * thread-default main context. */
      task = g_task_new (NULL, NULL, callback, user_data);
      g_task_set_task_data (task, data,
                            (GDestroyNotify) my_func_data_free);
    
      /* Invoke the function. */
      g_main_context_invoke_full (thread1_main_context,
                                  G_PRIORITY_DEFAULT, my_func_idle,
                                  task,
                                  (GDestroyNotify) g_object_unref);
    }
cs: 
    /* Toto bude vyvoláno ve vlákně thread1 */
    static gboolean
    my_func_idle (gpointer user_data)
    {
      GTask *task = G_TASK (user_data);
      MyFuncData *data;
      gboolean retval;
    
      /* Zavolá my_func() a vrácenou pravdivostní hodnotu propaguje
       * do hlavního vlákna */
      data = g_task_get_task_data (task);
      retval = my_func (data-&gt;some_string, data-&gt;some_int,
                        data-&gt;some_object);
      g_task_return_boolean (task, retval);
    
      return G_SOURCE_REMOVE;
    }
    
    /* Ať je toto vyvoláno z kteréhokoliv vlákna, vyvolá se funkce
     * @callback, jakmile je dokončena my_func() a vrátí výsledek */
    static void
    invoke_my_func_with_result (GMainContext        *thread1_main_context,
                                const gchar         *some_string,
                                guint                some_int,
                                GObject             *some_object,
                                GAsyncReadyCallback  callback,
                                gpointer             user_data)
    {
      MyFuncData *data;
    
      /* Vytvoří zapouzdření dat pro předání všech požadovaných proměnných
       * mezi vlákny */
      data = g_new0 (MyFuncData, 1);
      data-&gt;some_string = g_strdup (some_string);
      data-&gt;some_int = some_int;
      data-&gt;some_object = g_object_ref (some_object);
    
      /* Vytvoří GTask pro obsluhu vráceného výsledku do hlavního výchozího
       * kontextu aktuálního vlákna */
      task = g_task_new (NULL, NULL, callback, user_data);
      g_task_set_task_data (task, data,
                            (GDestroyNotify) my_func_data_free);
    
      /* Vyvolá funkci */
      g_main_context_invoke_full (thread1_main_context,
                                  G_PRIORITY_DEFAULT, my_func_idle,
                                  task,
                                  (GDestroyNotify) g_object_unref);
    }

note: (itstool) path: info/desc
en: Managing memory allocation and deallocation in C
cs: Správa přidělování a uvolňování paměti v C

note: (itstool) path: page/title
en: Memory Management
cs: Správa paměti

note: (itstool) path: page/p
en: The GNOME stack is predominantly written in C, so dynamically allocated memory has to be managed manually. Through use of GLib convenience APIs, memory management can be trivial, but programmers always need to keep memory in mind when writing code.
cs: Zásobník GNOME je napsán převážně v jazyce C, takže dynamicky alokovaná paměť musí být spravována ručně. S použitím usnadňujícího API z GLib je však správa triviální, přesto by měli programátoři při psaní kódu na paměť vždy myslet.

note: (itstool) path: page/p
en: It is assumed that the reader is familiar with the idea of heap allocation of memory using <code>malloc()</code> and <code>free()</code>, and knows of the paired GLib equivalents, <code>g_malloc()</code> and <code>g_free()</code>.
cs: Předpokládá se, že čtenář je dobře seznámen s principem alokace paměti na haldě s pomocí <code>malloc()</code> a <code>free()</code> a zná příslušnou dvojici obdobných funkcí z GLib <code>g_malloc()</code> a <code>g_free()</code>.

note: (itstool) path: synopsis/p
en: There are three situations to avoid, in order of descending importance:
cs: Existují tři situace, kterým byste se měli vyhnout a které zde uvádíme podle důležitosti:

note: (itstool) path: item/p
en: Using memory after freeing it (use-after-free).
cs: Použití paměti po jejím uvolnění.

note: (itstool) path: item/p
en: Using memory before allocating it.
cs: Požití paměti před jejím přidělením.

note: (itstool) path: item/p
en: Not freeing memory after allocating it (leaking).
cs: Neuvolnění paměti, která byla přidělena (tzv. únik).

note: (itstool) path: synopsis/p
en: Key principles, in no particular order:
cs: Klíčové principy (bez ohledu na pořadí důležitosti):

note: (itstool) path: item/p
en: Determine and document whether each variable is owned or unowned. They must never change from one to the other at runtime. (<link xref="#principles"/>)
cs: U každé proměnné určete a zdokumentujte, zda je či není vlastněna. Za běhu se to pak nikdy nesmí měnit. (<link xref="#principles"/>)

note: (itstool) path: item/p
en: Determine and document the ownership transfers at function boundaries. (<link xref="#principles"/>)
cs: Určete a zdokumentujte přenosy vlastnictví na hranicích funkcí. (<link xref="#principles"/>)

note: (itstool) path: item/p
en: Ensure that each assignment, function call and function return respects the relevant ownership transfers. (<link xref="#assignments"/>, <link xref="#function-calls"/>, <link xref="#function-returns"/>)
cs: Zajistěte, aby každé přiřazení, volání funkce a návrat z funkce respektovali příslušné přenosy vlastnictví. (<link xref="#assignments"/>, <link xref="#function-calls"/>, <link xref="#function-returns"/>)

note: (itstool) path: item/p
en: Use reference counting rather than explicit finalization where possible. (<link xref="#reference-counting"/>)
cs: Kde je to možné, používejte raději počítání odkazů, než explicitní finalizaci. (<link xref="#reference-counting"/>)

note: (itstool) path: item/p
en: Use GLib convenience functions like <link xref="#g-clear-object"><code>g_clear_object()</code></link> where possible. (<link xref="#convenience-functions"/>)
cs: Kde je to možné, používejte vhodné funkce z GLib, jako třeba <link xref="#g-clear-object"><code>g_clear_object()</code></link>. (<link xref="#convenience-functions"/>)

note: (itstool) path: item/p
en: Do not split memory management across code paths. (<link xref="#principles"/>)
cs: Nerozdělujte správu paměti do více cest průchodu programem. (<link xref="#principles"/>)

note: (itstool) path: item/p
en: Use the single-path cleanup pattern for large or complex functions. (<link xref="#single-path-cleanup"/>)
cs: Používejte návrhový vzor pro jednocestné čištění pro rozsáhlé a složité funkce. (<link xref="#single-path-cleanup"/>)

note: (itstool) path: item/p
en: Leaks should be checked for using Valgrind or the address sanitizer. (<link xref="#verification"/>)
cs: Uniky by měly být kontrolovány pomocí nástroje Valgrind nebo sanitizérem adres. (<link xref="#verification"/>)

note: (itstool) path: section/title
en: Principles of Memory Management
cs: Principy správy paměti

note: (itstool) path: section/p
en: The normal approach to memory management is for the programmer to keep track of which variables point to allocated memory, and to manually free them when they are no longer needed. This is correct, but can be clarified by introducing the concept of <em>ownership</em>, which is the piece of code (such as a function, struct or object) which is responsible for freeing a piece of allocated memory (an <em>allocation</em>). Each allocation has exactly one owner; this owner may change as the program runs, by <em>transferring</em> ownership to another piece of code. Each variable is <em>owned</em> or <em>unowned</em>, according to whether the scope containing it is always its owner. Each function parameter and return type either transfers ownership of the values passed to it, or it doesn’t. If code which owns some memory doesn’t deallocate that memory, that’s a memory leak. If code which doesn’t own some memory frees it, that’s a double-free. Both are bad.
cs: Normální přístup ke správě paměti spočívá pro programátora v tom, mít přehled, které proměnné ukazují na alokovanou paměť a ručně ji uvolnit v situaci, kdy již není nadále potřeba. Tak je to v pořádku, ale dá se to zpřehlednit zavedením konceptu <em>vlastnictví</em>, což je kus kódu (například funkce, struktura nebo objekt), který je zodpovědný za uvolnění kusu alokované paměti (<em>alokace</em>). Každá alokace má právě jednoho vlastníka, který se ale za dobu běhu programu může měnit tzv. <em>přenosem</em> vlastnictví na jiný kus kódu. Každá proměnná je buď <em>vlastněna</em> nebo <em>nevlastněna</em>, podle toho, jestli je rozsah působnosti, jehož je součástí, vždy jejím vlastníkem. Každý parametr funkce a návratový typ buď přenáší vlastnictví předávané hodnoty nebo nepřenáší. V případě, že kód vlastnící nějakou paměti tuto paměť nedealokuje, dojde k úniku paměti. V případě, že kód, který nevlastní určitou paměť, tuto paměť uvolní, jedná se o dvojité uvolnění. Obojí je špatně.

note: (itstool) path: section/p
en: By statically calculating which variables are owned, memory management becomes a simple task of unconditionally freeing the owned variables before they leave their scope, and <em>not</em> freeing the unowned variables (see <link xref="#single-path-cleanup"/>). The key question to answer for all memory is: which code has ownership of this memory?
cs: Tím, že stačí napevno určit, které proměnné jsou vlastněné, se ze správy paměti stává jednoduchý úkol spočívající v nepodmíněném uvolňování proměnných před tím, než se opustí jejich rozsah působnosti, a v <em>ne</em>uvolnění nevlastněných proměnných (viz <link xref="#single-path-cleanup"/>). Klíčovou otázkou pro kterýkoliv kus paměti tak je: která část kódu jej vlastní.

note: (itstool) path: section/p
en: There is an important restriction here: variables must <em style="strong">never</em> change from owned to unowned (or vice-versa) at runtime. This restriction is key to simplifying memory management.
cs: Je zde jedno důležité omezení: proměnné se za běhu <em style="strong">nikdy</em> nesmí změnit z vlastněných na nevlastněné (nebo naopak). Toto omezení je klíčové kvůli zjednodušení správy paměti.

note: (itstool) path: section/p
en: For example, consider the functions:
cs: Například mějme funkci:

note: (itstool) path: section/p
en: The following code has been annotated to note where the ownership transfers happen:
cs: Následující kód byl opatřen anotacemi a komentáři, abyste se všimli, kde dochází k přenosu vlastnictví:

note: (itstool) path: section/code
en: gchar *my_str = NULL;  /* owned */
    const gchar *template;  /* unowned */
    GValue value = G_VALUE_INIT;  /* owned */
    g_value_init (&amp;value, G_TYPE_STRING);
    
    /* Transfers ownership of a string from the function to the variable. */
    template = "XXXXXX";
    my_str = generate_string (template);
    
    /* No ownership transfer. */
    print_string (my_str);
    
    /* Transfer ownership. We no longer have to free @my_str. */
    g_value_take_string (&amp;value, my_str);
    
    /* We still have ownership of @value, so free it before it goes out of scope. */
    g_value_unset (&amp;value);
cs: gchar *my_str = NULL;  /* owned */
    const gchar *template;  /* unowned */
    GValue value = G_VALUE_INIT;  /* owned */
    g_value_init (&amp;value, G_TYPE_STRING);
    
    /* Přenese vlastnictví řetězce z funkce do proměnné */
    template = "XXXXXX";
    my_str = generate_string (template);
    
    /* Bez přenosu vlastnictví */
    print_string (my_str);
    
    /* Přenos vlastnictví. Nadále se již nemusíme starat o uvolnění @my_str. */
    g_value_take_string (&amp;value, my_str);
    
    /* Stále vlastníme @value, takže před opuštěním této oblasti působnosti ji musíme uvolnit */
    g_value_unset (&amp;value);

note: (itstool) path: section/p
en: There are a few points here: Firstly, the ‘owned’ comments by the variable declarations denote that those variables are owned by the local scope, and hence need to be freed before they go out of scope. The alternative is ‘unowned’, which means the local scope does <em>not</em> have ownership, and <em>must not</em> free the variables before going out of scope. Similarly, ownership <em>must not</em> be transferred to them on assignment.
cs: Zastavme se u několika věcí: Za prvé, komentáře „vlastněno“ u deklarací proměnných naznačují, že tyto proměnné jsou vlastněné místním rozsahem působnosti, a proto potřebují být uvolněné před opuštěním tohoto rozsahu působnosti. Alternativou je „nevlastněno“, což znamená, že místní rozsah působnosti <em>nemá</em> vlastnictví a <em>nemusí</em> proměnnou uvolnit před opuštěním rozsahu působnosti. Obdobně, při přiřazení na něj vlastnictví <em>nemusí</em> být přeneseno.

note: (itstool) path: section/p
en: Secondly, the variable type modifiers reflect whether they transfer ownership: because <code>my_str</code> is owned by the local scope, it has type <code>gchar</code>, whereas <code>template</code> is <code>const</code> to denote it is unowned. Similarly, the <code>template</code> parameter of <code>generate_string()</code> and the <code>str</code> parameter of <code>print_string()</code> are <code>const</code> because no ownership is transferred when those functions are called. As ownership <em>is</em> transferred for the string parameter of <code>g_value_take_string()</code>, we can expect its type to be <code>gchar</code>.
cs: Za druhé, modifikatory u proměnných odrážejí, jestli dochází k přenosu vlastnictví: protože <code>my_str</code> je vlastněna místním rozsahem působnosti, je typu <code>gchar</code>, zatímco <code>template</code> je <code>const</code>, což říká, že není vlastněna. Obdobně, parametr <code>template</code> funkce <code>generate_string()</code> a parametr <code>str</code> funkce <code>print_string()</code> jsou <code>const</code>, protože není přenášeno vlastnictví při volání těchto funkcí. Protože pro řetězcový parametr funkce <code>g_value_take_string()</code> <em>je</em> přenášeno vlastnictví, očekáváme, že její typ je <code>gchar</code>.

note: (itstool) path: section/p
en: (Note that this is not the case for <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html"> <code>GObject</code></link>s and subclasses, which can never be <code>const</code>. It is only the case for strings and simple <code>struct</code>s.)
cs: (Upozorňujeme, že toto se netýká objektu <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html"><code>GObject</code></link> a podtříd, které nemohou být nikdy <code>const</code>. Týká se to jen řetězců a jednoduchých struktur <code>struct</code>.)

note: (itstool) path: section/p
en: Finally, a few libraries use a function naming convention to indicate ownership transfer, for example using ‘take’ in a function name to indicate full transfer of parameters, as with <code>g_value_take_string()</code>. Note that different libraries use different conventions, as shown below:
cs: A na konec, pár knihoven používá zvyklosti v názvech funkcí k indikaci přenosu vlastnictví, například pomocí „take“ v názvu funkce, čímž oznamují úplný přenos parametru, jako třeba u <code>g_value_take_string()</code>. Dávajte ale pozor na to, že různé knihovny používají různé konvence, jak je ukázáno níže:

note: (itstool) path: td/p
en: Function name
cs: Název funkce

note: (itstool) path: td/p
en: Convention 1 (standard)
cs: Konvence 1 (standardní)

note: (itstool) path: td/p
en: Convention 2 (alternate)
cs: Konvence 2 (alternativní)

note: (itstool) path: td/p
en: Convention 3 (<cmd>gdbus-codegen</cmd>)
cs: Konvence 3 (<cmd>gdbus-codegen</cmd>)

note: (itstool) path: td/p
en: No transfer
cs: Bez přenosu

note: (itstool) path: td/p
en: Any transfer
cs: Libovolný přenos

note: (itstool) path: td/p
en: Full transfer
cs: Úplný přenos

note: (itstool) path: td/p
en: Unused
cs: Nepoužito

note: (itstool) path: section/p
en: Ideally, all functions have a <code>(transfer)</code> <link xref="introspection">introspection annotation</link> for all relevant parameters and the return value. Failing that, here is a set of guidelines to use to determine whether ownership of a return value is transferred:
cs: V ideálním případě mají všechny funkce <link xref="introspection">anotaci k introspekci</link> ve formě <code>(transfer)</code> pro všechny příslušné parametry a návratovou hodnotu. Pokud tomu tak není, uvádíme zde sadu pravidel, které můžete použít k určení toho, jestli je vlastnictví návratové hodnoty přenášeno:

note: (itstool) path: item/p
en: If the type has an introspection <code>(transfer)</code> annotation, look at that.
cs: Jestliže má typ uvedenou anotaci <code>(transfer)</code> k introspekci, podívejte se na ni.

note: (itstool) path: item/p
en: Otherwise, if the type is <code>const</code>, there is no transfer.
cs: V ostatních případech, když je typ konstantní (<code>const</code>), nedochází k přenosu.

note: (itstool) path: item/p
en: Otherwise, if the function documentation explicitly specifies the return value must be freed, there is full or container transfer.
cs: Jinak, jestliže dokumentace k funkci výslovně uvádí, že návratová hodnota musí být uvolněna, jedná se o úplný nebo kontejnerový přenos.

note: (itstool) path: item/p
en: Otherwise, if the function is named ‘dup’, ‘take’ or ‘steal’, there is full or container transfer.
cs: V ostatních případech, když se funkce nazývá „dup“, „take“ nebo „steal“, dochází k úplnému nebo kontejnerovému přenosu.

note: (itstool) path: item/p
en: Otherwise, if the function is named ‘peek’, there is no transfer.
cs: V ostatních případech, když se funkce nazývá „peek“, nedochází k přenosu.

note: (itstool) path: item/p
en: Otherwise, you need to look at the function’s code to determine whether it intends ownership to be transferred. Then file a bug against the documentation for that function, and ask for an introspection annotation to be added.
cs: Jinak se musíte podívat do kódu funkce, abyste určili, jestli zamýšlí vlastnictví přenášet. Nahlaste také chybu vůči dokumentaci této funkce a v hlášení požádejte o přidání anotace k introspekci.

note: (itstool) path: section/p
en: Given this ownership and transfer infrastructure, the correct approach to memory allocation can be mechanically determined for each situation. In each case, the <code>copy()</code> function must be appropriate to the data type, for example <code>g_strdup()</code> for strings, or <code>g_object_ref()</code> for GObjects.
cs: Když máme vlastnictví a přenos takhle jasně dány, je správný přístup k alokaci paměti v kterékoliv situaci otázkou mechanického rozhodnutí. V každém případě, funkce <code>copy()</code> musí odpovídat datovému typu, například <code>g_strdup()</code> pro řetězec nebo <code>g_object_ref()</code> pro GObject.

note: (itstool) path: section/p
en: When thinking about ownership transfer, <code>malloc()</code>/<code>free()</code> and reference counting are equivalent: in the former case, a newly allocated piece of heap memory is transferred; in the latter, a newly incremented reference. See <link xref="#reference-counting"/>.
cs: Když se nad přenosem vlastnictví zamyslíte, jsou <code>malloc()</code>/<code>free()</code> a počítání referencí to stejné: v prvním případě je naalokování nového kusu paměti z haldy přenosem vlastnictví, ve druhém případě nové zvýšení referencí. Viz <link xref="#reference-counting"/>.

note: (itstool) path: section/title
en: Assignments
cs: Přiřazení

note: (itstool) path: td/p
en: Assignment from/to
cs: Přiřazení z/do

note: (itstool) path: td/p
en: Owned destination
cs: Vlastněný cíl

note: (itstool) path: td/p
en: Unowned destination
cs: Nevlastněný cíl

note: (itstool) path: td/p
en: Owned source
cs: Vlastněný zdroj

note: (itstool) path: td/p
en: Copy or move the source to the destination.
cs: Kopírování nebo přesun zdroje do cíle.

note: (itstool) path: td/p
en: Pure assignment, assuming the unowned variable is not used after the owned one is freed.
cs: Prosté přiřazení, předpokládá se, že nevlastněná proměnná se nepoužije po té, co je vlastněná uvolněna.

note: (itstool) path: td/p
en: Unowned source
cs: Nevlastněný zdroj

note: (itstool) path: td/p
en: Copy the source to the destination.
cs: Kopírování zdroje do cíle.

note: (itstool) path: td/p
en: Pure assignment.
cs: Prosté přiřazení.

note: (itstool) path: section/title
en: Function Calls
cs: Volání funkcí

note: (itstool) path: td/p
en: Call from/to
cs: Volání z/do

note: (itstool) path: td/p
en: Transfer full parameter
cs: Přenos úplného parametru

note: (itstool) path: td/p
en: Transfer none parameter
cs: Žádný přenos parametru

note: (itstool) path: td/p
en: Copy or move the source for the parameter.
cs: Kopírování nebo přesun zdroje pro parametr.

note: (itstool) path: td/p
en: Pure parameter passing.
cs: Prosté předání parametru.

note: (itstool) path: td/p
en: Copy the source for the parameter.
cs: Kopírování zdroje pro parametr.

note: (itstool) path: section/title
en: Function Returns
cs: Návrat z funkcí

note: (itstool) path: td/p
en: Return from/to
cs: Návrat z/do

note: (itstool) path: td/p
en: Transfer full return
cs: Přenos úplné návratové hodnoty

note: (itstool) path: td/p
en: Transfer none return
cs: Žádný přenos návratové hodnoty

note: (itstool) path: td/p
en: Pure variable return.
cs: Prostý návrat proměnné.

note: (itstool) path: td/p
en: Invalid. The source needs to be freed, so the return value would use freed memory — a use-after-free error.
cs: Neplatné. Zdroj potřebuje být uvolněn, takže vrácená hodnota by používala volnou paměť — chyba „použití po uvolnění“.

note: (itstool) path: td/p
en: Copy the source for the return.
cs: Kopírování zdroje pro návratovou hodnotu.

note: (itstool) path: td/p
en: Pure variable passing.
cs: Prosté předání proměnné.

note: (itstool) path: section/p
en: Documenting the ownership transfer for each function parameter and return, and the ownership for each variable, is important. While they may be clear when writing the code, they are not clear a few months later; and may never be clear to users of an API. They should always be documented.
cs: Zdokumentování přenosu vlastnictví u každého parametru funkce a návratové hodnoty a vlastnictví u každé proměnné je velmi důležité. Zatím co při psaní kódu to může být zcela jasné, o pár měsíců později to již tak jasné být nemusí. A už vůbec to nemusí být jasné uživatelům API. Proto by to mělo být vždy zdokumentováno.

note: (itstool) path: section/p
en: The best way to document ownership transfer is to use the <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Memory_and_lifecycle_management"> <code>(transfer)</code></link> annotation introduced by <link xref="introspection">gobject-introspection</link>. Include this in the API documentation comment for each function parameter and return type. If a function is not public API, write a documentation comment for it anyway and include the <code>(transfer)</code> annotations. By doing so, the introspection tools can also read the annotations and use them to correctly introspect the API.
cs: Nejlepším způsobem zdokumentování přenosu vlastnictví je použít anotaci <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Memory_and_lifecycle_management"><code>(transfer)</code></link>, která byla zavedena spolu s <link xref="introspection">introspekcí pro GObject</link>. Uveďte ji do dokumentačních komentářů k API pro všechny parametry a návratové typy funkcí. I když funkce není veřejným API, napište k ní dokumentační komentář a do něj zahrňte anotaci <code>(transfer)</code>. Díky tomu budo moci nástroje pro introspekci číst potřebné anotace a správně prozkoumávat API.

note: (itstool) path: section/p
en: Ownership for variables can be documented using inline comments. These are non-standard, and not read by any tools, but can form a convention if used consistently.
cs: Vlastnictví proměnných lze dokumentovat pomocí vložených komentářů. Není to standardem a nečtou to všechny nástroje, ale může se to stát zvyklostí, pokud to bude jednotně dodržováno.

note: (itstool) path: section/p
en: The documentation for <link xref="#container-types"/> is similarly only a convention; it includes the type of the contained elements too:
cs: Obdobně i dokumentování pro <link xref="#container-types"/> je čistě jen zvyklost. Součástí je také typ obsaženého prvku:

note: (itstool) path: section/p
en: Note also that owned variables should always be initialized so that freeing them is more convenient. See <link xref="#convenience-functions"/>.
cs: Pamatujte také, že vlastněné proměnné by měly být vždy inicializovány, takže jejich uvolnění je pak mnohem pohodlnější. Viz <link xref="#convenience-functions"/>.

note: (itstool) path: section/p
en: Also note that some types, for example basic C types like strings, can have the <code>const</code> modifier added if they are unowned, to take advantage of compiler warnings resulting from assigning those variables to owned variables (which must <em>not</em> use the <code>const</code> modifier). If so, the <code>/* unowned */</code> comment may be omitted.
cs: Poznamenejme také, že některé typy, například základní typy v C, jako je řetězec, mohou mít v případě, že nejsou vlastněny, přidán modifikátor <code>const</code>, což má výhodu, že kompilátor zobrazí varování, když se pokusíte takovouto proměnnou přiřadit do vlastněné proměnné (která modifikátor <code>const</code> použít <em>nesmí</em>). V případě použití modifikátoru je možné vynechat komentář <code>/* unowned */</code>.

note: (itstool) path: section/title
en: Reference Counting
cs: Počítání odkazů

note: (itstool) path: section/p
en: As well as conventional <code>malloc()</code>/<code>free()</code>-style types, GLib has various reference counted types — <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html"> <code>GObject</code></link> being a prime example.
cs: Mimo tradičních typů ve stylu <code>malloc()</code>/<code>free()</code> máte v GLib k dispozici i různé typy počítání referencí — základním příkladem je <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html"> <code>GObject</code></link>.

note: (itstool) path: section/p
en: The concepts of ownership and transfer apply just as well to reference counted types as they do to allocated types. A scope <em>owns</em> a reference counted type if it holds a strong reference to the instance (for example by calling <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref"> <code>g_object_ref()</code></link>). An instance can be ‘copied’ by calling <code>g_object_ref()</code> again. Ownership can be freed with <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref"> <code>g_object_unref()</code></link> — even though this may not actually finalize the instance, it frees the current scope’s ownership of that instance.
cs: Koncept vlastnictví a jeho přenosu se používá stejně jako počítání referencí, které dělají alokované typy. Rozsah působnosti <em>vlastní</em> typy s počítáním referencí, pokud drží silnou referenci na instanci (například zavoláním <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref"><code>g_object_ref()</code></link>. Instance se dá „zkopírovat“ opětovným zavoláním <code>g_object_ref()</code>. Vlastnictví se dá uvolnit pomocí <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref"><code>g_object_unref()</code></link> — i když se tím nemusí ve skutečnosti ukončit instance, uvolní se tím vlastnictví instance v aktuálním rozsahu působnosti.

note: (itstool) path: section/p
en: See <link xref="#g-clear-object"/> for a convenient way of handling GObject references.
cs: Viz <link xref="#g-clear-object"/> ohledně vhodného způsobu zacházení s referencemi GObject.

note: (itstool) path: section/p
en: There are other reference counted types in GLib, such as <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html"> <code>GHashTable</code></link> (using <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-ref"> <code>g_hash_table_ref()</code></link> and <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-unref"> <code>g_hash_table_unref()</code></link>), or <link href="https://developer.gnome.org/glib/stable/glib-GVariant.html"> <code>GVariant</code></link> (<link href="https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-ref"> <code>g_variant_ref()</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-unref"> <code>g_variant_unref()</code></link>). Some types, like <code>GHashTable</code>, support both reference counting and explicit finalization. Reference counting should always be used in preference, because it allows instances to be easily shared between multiple scopes (each holding their own reference) without having to allocate multiple copies of the instance. This saves memory.
cs: V GLib existují další typy s počítáním referencí, jako je <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html"> <code>GHashTable</code></link> (používá <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-ref"> <code>g_hash_table_ref()</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-unref"> <code>g_hash_table_unref()</code></link>), nebo <link href="https://developer.gnome.org/glib/stable/glib-GVariant.html"> <code>GVariant</code></link> (<link href="https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-ref"> <code>g_variant_ref()</code></link>, <link href="https://developer.gnome.org/glib/stable/glib-GVariant.html#g-variant-unref"> <code>g_variant_unref()</code></link>). Některé typy, jako <code>GHashTable</code> podporují jak počítání referencí, tak vynucenou finalizaci. Použití počítání referencí by se měla vždy dávat přednost, protože umožňuje instancím se jednoduše sdílet mezi více rozsahy působnosti (každá se drží svoji vlastní referenci), bez nutnosti alokovat více kopií instance. Šetří se tím paměť.

note: (itstool) path: section/title
en: Floating References
cs: Plovoucí reference

note: (itstool) path: section/p
en: Classes which are derived from <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GInitiallyUnowned"><code>GInitiallyUnowned</code></link>, as opposed to <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GObject-struct"><code>GObject</code></link> have an initial reference which is <em>floating</em>, meaning that no code owns the reference. As soon as <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref-sink"><code>g_object_ref_sink()</code></link> is called on the object, the floating reference is converted to a strong reference, and the calling code assumes ownership of the object.
cs: Třídy odvozené z <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GInitiallyUnowned"><code>GInitiallyUnowned</code></link> mají, oproti <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GObject-struct"><code>GObject</code></link>, počáteční referenci, která je <em>plovoucí</em>, což znamená, že ji nevlastní žádný kód. Jakmile je zavolána funkce <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref-sink"><code>g_object_ref_sink()</code></link>, změní se plovoucí reference na silnou referenci a volající kód je pokládán za vlastníka objektu.

note: (itstool) path: section/p
en: Floating references are a convenience for use in C in APIs, such as GTK+, where large numbers of objects must be created and organized into a hierarchy. In these cases, calling <code>g_object_unref()</code> to drop all the strong references would result in a lot of code.
cs: Plovoucí reference jsou vhodné pro použití v jazyce C v takových API, jako je GTK+, kde je zapotřebí vytvářet a organizovat do hierarchie velké množství objektů. V takových případech by zavolání <code>g_object_unref()</code> kvůli zachození všech silných referencí vedlo na velké množství kódu.

note: (itstool) path: example/p
en: Floating references allow the following code to be simplified:
cs: Plovoucí reference umožňují následující kód zjednodušit:

note: (itstool) path: example/p
en: Instead, the following code can be used, with the <code>GtkContainer</code> assuming ownership of the floating reference:
cs: Místo toho můžete použít následující kód s <code>GtkContainer</code> předpokládajícím vlastnictví plovoucí reference:

note: (itstool) path: section/p
en: Floating references are only used by a few APIs — in particular, <code>GtkWidget</code> and all its subclasses. You must learn which APIs support it, and which APIs consume floating references, and only use them together.
cs: Plovoucí reference používá jen pár API, zejména to je <code>GtkWidget</code> a všechny jeho podtřídy. Musíte si zjistit, která API je podporují a která API je umějí přijímat a používat je jen dohromady.

note: (itstool) path: section/p
en: Note that <code>g_object_ref_sink()</code> is equivalent to <code>g_object_ref()</code> when called on a non-floating reference, making <code>gtk_container_add()</code> no different from any other function in such cases.
cs: Všimněte si, že <code>g_object_ref_sink()</code> se chová stejně jako <code>g_object_ref()</code>, když je zavolána na neplovoucí referenci, díky čemuž se <code>gtk_container_add()</code> neliší v takovýchto případech od jiných funkcí.

note: (itstool) path: section/p
en: See the <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#floating-ref">GObject manual</link> for more information on floating references.
cs: Více informací o plovoucích referencích najdete v <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#floating-ref">příručce k GObject</link>.

note: (itstool) path: section/title
en: Convenience Functions
cs: Vhodné funkce

note: (itstool) path: section/p
en: GLib provides various convenience functions for memory management, especially for GObjects. Three will be covered here, but others exist — check the GLib API documentation for more. They typically follow similar naming schemas to these three (using ‘_full’ suffixes, or the verb ‘clear’ in the function name).
cs: GLib poskytuje řadu funkcí usnadňujících správu paměti, hlavně pro GObject. Tři z nich jsou zde rozebrány, ale existují i další — podívejte se na ně do dokumentace k API GLib. Typicky dodržují podobné schéma pojmenování, jako zmíněné tři (používají sufix „_full“ nebo sloveso „clear“ v názvu).

note: (itstool) path: section/p
en: <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-clear-object"> <code>g_clear_object()</code></link> is a version of <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref"> <code>g_object_unref()</code></link> which unrefs a GObject and then clears the pointer to it to <code>NULL</code>.
cs: <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-clear-object"><code>g_clear_object()</code></link> je verzí funkce <link href="https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-unref"><code>g_object_unref()</code></link>, která zruší referenci na GObject a vymaže ukazatel nastavením na <code>NULL</code>.

note: (itstool) path: section/p
en: This makes it easier to implement code that guarantees a GObject pointer is always either <code>NULL</code>, or has ownership of a GObject (but which never points to a GObject it no longer owns).
cs: Díky tomu je snazší napsat programový kód, který zaručuje, že ukazatel na GObject je vždy buď <code>NULL</code> nebo je vlastněn objektem GObject (ale nikdy neukazuje na GObject, který již není vlastněn).

note: (itstool) path: section/p
en: By initialising all owned GObject pointers to <code>NULL</code>, freeing them at the end of the scope is as simple as calling <code>g_clear_object()</code> without any checks, as discussed in <link xref="#single-path-cleanup"/>:
cs: Tím, že inicializujete všechny vlastněné ukazatel na GObject na <code>NULL</code>, je jejich uvolnění na konci oblasti působnosti možné pouhým zavoláním <code>g_clear_object()</code> bez jakýchkoliv kontrol, tak jak je to probráno v <link xref="#single-path-cleanup"/>:

note: (itstool) path: section/code
en: void
    my_function (void)
    {
      GObject *some_object = NULL;  /* owned */
    
      if (rand ())
        {
          some_object = create_new_object ();
          /* do something with the object */
        }
    
      g_clear_object (&amp;some_object);
    }
cs: void
    my_function (void)
    {
      GObject *some_object = NULL;  /* owned */
    
      if (rand ())
        {
          some_object = create_new_object ();
          /* zde se s objektem něco udělá */
        }
    
      g_clear_object (&amp;some_object);
    }

note: (itstool) path: section/p
en: <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free-full"> <code>g_list_free_full()</code></link> frees all the elements in a linked list, <em>and all their data</em>. It is much more convenient than iterating through the list to free all the elements’ data, then calling <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free"> <code>g_list_free()</code></link> to free the <code>GList</code> elements themselves.
cs: <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free-full"> <code>g_list_free_full()</code></link> uvolní všechny prvky v zřetězeném seznamu <em>a všechna jejich data</em>. To je mnohem pohodlnější, než procházet celý seznam, abyste uvolnily data jednotlivých prvků a následně zavolat <link href="https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html#g-list-free"> <code>g_list_free()</code></link>, aby se uvolnily vlastní prvky seznamu <code>GList</code>.

note: (itstool) path: section/p
en: <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new-full"> <code>g_hash_table_new_full()</code></link> is a newer version of <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new"> <code>g_hash_table_new()</code></link> which allows setting functions to destroy each key and value in the hash table when they are removed. These functions are then automatically called for all keys and values when the hash table is destroyed, or when an entry is removed using <code>g_hash_table_remove()</code>.
cs: <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new-full"> <code>g_hash_table_new_full()</code></link> je novou verzí funkce <link href="https://developer.gnome.org/glib/stable/glib-Hash-Tables.html#g-hash-table-new"><code>g_hash_table_new()</code></link>, která umožňuje nastavit funkce pro likvidaci jednotlivých klíčů a hodnot hašovací tabulky při jejím odstranění. Tyto funkce jsou pak automaticky volány pro všechny klíče a hodnoty, když je hašovací tabulka likvidována nebo když je odstraněna položka pomocí <code>g_hash_table_remove()</code>.

note: (itstool) path: section/p
en: Essentially, it simplifies memory management of keys and values to the question of whether they are present in the hash table. See <link xref="#container-types"/> for a discussion on ownership of elements within container types.
cs: V podstatě to zjednodušuje správu paměti s klíči a hodnotami na otázku, jestli se nacházejí v hašovací tabulce. Vlastnictví prvku v kontejnerových typech je rozebráno v <link xref="#container-types"/>.

note: (itstool) path: section/p
en: A similar function exists for <code>GPtrArray</code>: <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-new-with-free-func"> <code>g_ptr_array_new_with_free_func()</code></link>.
cs: Obdobná funkce existuje pro <code>GPtrArray</code>: <link href="https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-new-with-free-func"><code>g_ptr_array_new_with_free_func()</code></link>.

note: (itstool) path: section/title
en: Container Types
cs: Typy kontejnerů

note: (itstool) path: section/p
en: When using container types, such as <code>GPtrArray</code> or <code>GList</code>, an additional level of ownership is introduced: as well as the ownership of the container instance, each element in the container is either owned or unowned too. By nesting containers, multiple levels of ownership must be tracked. Ownership of owned elements belongs to the container; ownership of the container belongs to the scope it’s in (which may be another container).
cs: Při používání kontejnerových typů, jako je <code>GPtrArray</code> nebo <code>GList</code>, vzniká další úroveň vlastnictví: kromě vlastnictví instance kontejneru je také vlasněn nebo nevlastněn každý z prvků v kontejneru. Při vnoření kontejnerů pak musí být sledováno více úrovní vlastnictví. Vlastnictví vlastněných prvků náleží kontejneru a vlastnictví kontejneru náleží rozsahu působnosti kódu, ve kterém se nachází (což může být i další kontejner).

note: (itstool) path: section/p
en: A key principle for simplifying this is to ensure that all elements in a container have the same ownership: they are either all owned, or all unowned. This happens automatically if the normal <link xref="#convenience-functions"/> are used for types like <code>GPtrArray</code> and <code>GHashTable</code>.
cs: Klíčovým principem pro zjednodušení toho celého je, zajistit, aby všechny prvky v kontejneru měly stejného vlastníka: buď jsou všechny vlastněny nebo nejsou. To se děje automaticky, když jsou použity normální <link xref="#convenience-functions"/> pro typy, jako jsou <code>GPtrArray</code> a <code>GHashTable</code>.

note: (itstool) path: section/p
en: If elements in a container are <em>owned</em>, adding them to the container is essentially an ownership transfer. For example, for an array of strings, if the elements are owned, the definition of <code>g_ptr_array_add()</code> is effectively:
cs: Když kontejner prvky <em>vlastní</em>, pak je jejich přidání do kontejneru v podstatě přenosem vlastnictví. Například, pro pole řetězců, pokud jsou prvky vlastněny, je definice <code>g_ptr_array_add()</code> ve skutečnosti:

note: (itstool) path: section/p
en: So, for example, constant (unowned) strings must be added to the array using <code>g_ptr_array_add (array, g_strdup ("constant string"))</code>.
cs: Takže například konstantní (nevlastněný) řetězec musí být přidán do pole pomocí <code>g_ptr_array_add (array, g_strdup ("constant string"))</code>.

note: (itstool) path: section/p
en: Whereas if the elements are unowned, the definition is effectively:
cs: Zatímco, když prvek není vlastněn, je definice ve skutečnosti:

note: (itstool) path: section/p
en: Here, constant strings can be added without copying them: <code>g_ptr_array_add (array, "constant string")</code>.
cs: Zde může být konstantní řetězec přidán bez jeho kopírování: <code>g_ptr_array_add (array, "constant string")</code>.

note: (itstool) path: section/p
en: See <link xref="#documentation"/> for examples of comments to add to variable definitions to annotate them with the element type and ownership.
cs: Příklady komentářů, které se přidávají ke definicím proměnných kvůli anotacím k typu a vlastnictví, viz <link xref="#documentation"/>.

note: (itstool) path: section/title
en: Single-Path Cleanup
cs: Jednocestné čištění

note: (itstool) path: section/p
en: A useful design pattern for more complex functions is to have a single control path which cleans up (frees) allocations and returns to the caller. This vastly simplifies tracking of allocations, as it’s no longer necessary to mentally work out which allocations have been freed on each code path — all code paths end at the same point, so perform all the frees then. The benefits of this approach rapidly become greater for larger functions with more owned local variables; it may not make sense to apply the pattern to smaller functions.
cs: Vhodným návrhovým vzorem pro složitější funkce je mít v jediné cestě průchodu vyčištění (uvolnění) alokací a návrat k volajícímu. Tím se nesmírně zjednoduší sledování alokací, protože není nadále nutné přemýšlet na tím, které alokace již byly v jednotlivých cestách průchodu uvolněny – všechny cesty průchodu končí ve stejném bodě, za kterým teprve provádíte uvolnění. Výhody tohoto přístupu se rychle projeví u rozsáhlých funkcí s více vlastněnými lokálními proměnnými. Pro menší funkce tento návrhový vzor smysluplný být nemusí.

note: (itstool) path: section/p
en: This approach has two requirements:
cs: Tento přístup má dva předpoklady:

note: (itstool) path: item/p
en: The function returns from a single point, and uses <code>goto</code> to reach that point from other paths.
cs: Návrat z funkce je v jediném bodě a pro dosažení tohoto bodu z jiných míst se používá <code>goto</code>.

note: (itstool) path: item/p
en: All owned variables are set to <code>NULL</code> when initialized or when ownership is transferred away from them.
cs: Všechny vlastněné proměnné jsou při inicializaci nebo při přenosu vlastnictví pryč nastaveny na <code>NULL</code>.

note: (itstool) path: section/p
en: The example below is for a small function (for brevity), but should illustrate the principles for application of the pattern to larger functions:
cs: Příklad níže je pro malou funkci (kvůli stručnosti), ale měl by ukázat principy i pro aplikaci, které chce tento vzor použít pro rozsáhlé funkce:

note: (itstool) path: listing/title
en: Single-Path Cleanup Example
cs: Příklad jednocestného číštění

note: (itstool) path: listing/desc
en: Example of implementing single-path cleanup for a simple function
cs: Příklad implementace jednocestného čištění pro jednoduchou funkci

note: (itstool) path: listing/code
en: GObject *
    some_function (GError **error)
    {
      gchar *some_str = NULL;  /* owned */
      GObject *temp_object = NULL;  /* owned */
      const gchar *temp_str;
      GObject *my_object = NULL;  /* owned */
      GError *child_error = NULL;  /* owned */
    
      temp_object = generate_object ();
      temp_str = "example string";
    
      if (rand ())
        {
          some_str = g_strconcat (temp_str, temp_str, NULL);
        }
      else
        {
          some_operation_which_might_fail (&amp;child_error);
    
          if (child_error != NULL)
            {
              goto done;
            }
    
          my_object = generate_wrapped_object (temp_object);
        }
    
    done:
      /* Here, @some_str is either NULL or a string to be freed, so can be passed to
       * g_free() unconditionally.
       *
       * Similarly, @temp_object is either NULL or an object to be unreffed, so can
       * be passed to g_clear_object() unconditionally. */
      g_free (some_str);
      g_clear_object (&amp;temp_object);
    
      /* The pattern can also be used to ensure that the function always returns
       * either an error or a return value (but never both). */
      if (child_error != NULL)
        {
          g_propagate_error (error, child_error);
          g_clear_object (&amp;my_object);
        }
    
      return my_object;
    }
cs: GObject *
    some_function (GError **error)
    {
      gchar *some_str = NULL;  /* owned */
      GObject *temp_object = NULL;  /* owned */
      const gchar *temp_str;
      GObject *my_object = NULL;  /* owned */
      GError *child_error = NULL;  /* owned */
    
      temp_object = generate_object ();
      temp_str = "example string";
    
      if (rand ())
        {
          some_str = g_strconcat (temp_str, temp_str, NULL);
        }
      else
        {
          some_operation_which_might_fail (&amp;child_error);
    
          if (child_error != NULL)
            {
              goto done;
            }
    
          my_object = generate_wrapped_object (temp_object);
        }
    
    done:
      /* Zde je proměnná @some_str buď NULL nebo řetězec, který má být uvolněn, takže
       * může být předána do g_free() nepodmíněně.
       *
       * Obdobně, @temp_object je buď NULL nebo objekt, na nějž má být zrušena reference,
       * takže může být předána do g_clear_object() nepodmíněně. */
      g_free (some_str);
      g_clear_object (&amp;temp_object);
    
      /* Tento vzor může být použit také zajištění, že funcke vždy vrátí
       * buď nějakou chybu nebo návratovou hodnotu (ale nikdy obojí). */
      if (child_error != NULL)
        {
          g_propagate_error (error, child_error);
          g_clear_object (&amp;my_object);
        }
    
      return my_object;
    }

note: (itstool) path: section/title
en: Verification
cs: Ověření

note: (itstool) path: section/p
en: Memory leaks can be checked for in two ways: static analysis, and runtime leak checking.
cs: Úniky paměti mohou být kontrolovány dvěma způsoby: statickou analýzou a kontrolou úniků za běhu.

note: (itstool) path: section/p
en: Static analysis with tools like <link xref="tooling#coverity">Coverity</link>, the <link xref="tooling#clang-static-analyzer">Clang static analyzer</link> or <link xref="tooling#tartan">Tartan</link> can catch some leaks, but require knowledge of the ownership transfer of every function called in the code. Domain-specific static analyzers like Tartan (which knows about GLib memory allocation and transfer) can perform better here, but Tartan is quite a young project and still misses things (a low true positive rate). It is recommended that code be put through a static analyzer, but the primary tool for detecting leaks should be runtime leak checking.
cs: Statická analýza pomocí nástrojů, jako je <link xref="tooling#coverity">Coverity</link>, <link xref="tooling#clang-static-analyzer">statický analyzátor Clang</link> nebo <link xref="tooling#tartan">Tartan</link>, může zachytit některé úniky, ale potřebuje k tomu znalost přenosu vlastnictví u všech funkcí volaných v kódu. Statické analyzátory zaměřené na určitou oblast, jako Tartan (který zná alokaci paměti a přenosy knihovny GLib) si mohou vést lépe. Ale zrovna Tartan je poněkud mladý projekt a stále postrádá některé věci (nízkou četnost pravdivých hlášení). Ze zmíněných důvodů je doporučováno projít kód statickým analyzátorem, ale jako hlavní nástroj pro zjišťování úniků by měla být kontrola za běhu.

note: (itstool) path: section/p
en: Runtime leak checking is done using <link xref="tooling#valgrind">Valgrind</link>, using its <link xref="tooling#memcheck">memcheck</link> tool. Any leak it detects as ‘definitely losing memory’ should be fixed. Many of the leaks which ‘potentially’ lose memory are not real leaks, and should be added to the suppression file.
cs: Kontrola úniků za běhu se provádí pomocí <link xref="tooling#valgrind">Valgrind</link>, konkrétně nástrojem <link xref="tooling#memcheck">memcheck</link>. Kterýkoliv únik, který je detekován jako „trvalá ztráta paměti“, by měl být opraven. Řada úniků, které jsou „potenciální ztráta paměti“ ve skutečnosti žádné uniky nejsou a měly by být přidány do souboru pro potlačení.

note: (itstool) path: section/p
en: If compiling with a recent version of Clang or GCC, the <link xref="tooling#address-sanitizer">address sanitizer</link> can be enabled instead, and it will detect memory leaks and overflow problems at runtime, but without the difficulty of running Valgrind in the right environment. Note, however, that it is still a young tool, so may fail in some cases.
cs: Pokud kompilujete pomocí nejnovějších verzí Clang nebo GCC, můžete místo toho zapnout <link xref="tooling#address-sanitizer">sanitizér adres</link>, který bude za běhu detekovat problémy s úniky paměti a přetečením, ale bez složitosti běhu nástrojů Valgrind ve správném prostředí. Upozorňujeme ale, že se jedná stále o nevyzrálý nástroj, takže v některých případech může selhat.

note: (itstool) path: section/p
en: See <link xref="tooling#valgrind"/> for more information on using Valgrind.
cs: Další informace ohledně použití aplikace Valgrind viz <link xref="tooling#valgrind"/>.

note: (itstool) path: info/desc
en: Avoiding symbol conflicts between libraries by namespacing all APIs
cs: Jak předejít konfliktům v symbolech mezi knihovnami pomocí jmenných prostorů ve všech API

note: (itstool) path: page/title
en: Namespacing
cs: Jmenné prostory

note: (itstool) path: synopsis/p
en: If a library is namespaced correctly, it can define types and methods in its API which have the same names as those in another library, and a program can use both without conflicts. This is achieved by prefixing all types and method names with a namespace unique to the library.
cs: Když má knihovna přidělený správný jmenný prostor, může ve svém API definovat typy a metody, které mají stejné názvy jako v jiných knihovnách a program ji s nimi může použít souběžně, aniž by došlo ke konfliktům. Je toho dosaženo díky předřazení prefixu v podobě jedinečného jmenného prostoru knihovny před názvy všech typů a metod.

note: (itstool) path: section/title
en: GObject APIs
cs: API pro GObject

note: (itstool) path: section/p
en: Consistent and complete namespacing of symbols (functions and types) and files is important for two key reasons:
cs: Jednotné a úplné jmenné prostory symbolů (funkcí a typů) a souborů jsou důležité ze dvou hlavních důvodů:

note: (itstool) path: item/p
en: Establishing a convention which means developers have to learn fewer symbol names to use the library — they can guess them reliably instead.
cs: Zavedení zvyklostí, které pro vývojáře znamenají, že si stačí zapamatovat pár názvů symbolů, aby mohli knihovnu používat – zbytek si mohou snadno domyslet.

note: (itstool) path: item/p
en: Ensuring symbols from two projects do not conflict if included in the same file.
cs: Zajištění, že symboly ze dvou projektů nebudou ve vzájemném konfliktu, když jsou vložené do stejného souboru.

note: (itstool) path: section/p
en: The second point is important — imagine what would happen if every project exported a function called <code>create_object()</code>. The headers defining them could not be included in the same file, and even if that were overcome, the programmer would not know which project each function comes from. Namespacing eliminates these problems by using a unique, consistent prefix for every symbol and filename in a project, grouping symbols into their projects and separating them from others.
cs: Druhý bod je velmi důležitý — představte si, co by se stalo, když by každý projekt exportoval funkci nazvanou <code>create_object()</code>. Hlavičkové soubory, které by ji definovaly, by pak nemohly být vložené naráz ve stejném souboru. A i kdyby mohly, programátor by pak stejně nevěděl, ze kterého projektu je která. Jmenné prostory tento problém řeší pomocí použití jedinečného a jednotného prefixu pro všechny symboly a názvy souborů v projektu, čímž se symboly seskupí ve svém projektu a oddělí od ostatních projektů.

note: (itstool) path: section/p
en: The conventions below should be used for namespacing all symbols. They are <link href="https://developer.gnome.org/gobject/stable/gtype-conventions.html"> used in all GLib-based projects</link>, so should be familiar to a lot of developers:
cs: Konvence uvedené níže by se měly používat pro jmenné prostory všech symbolů. Jsou <link href="https://developer.gnome.org/gobject/stable/gtype-conventions.html">použity ve všech projektech založených na GLib</link>, a měly by tak být dobře známy velkému množství vývojářů:

note: (itstool) path: item/p
en: Functions should use <code>lower_case_with_underscores</code>.
cs: Funkce by měly používat <code>mala_pismena_s_podtrzitky</code>.

note: (itstool) path: item/p
en: Structures, types and objects should use <code>CamelCaseWithoutUnderscores</code>.
cs: Struktury, typy a objekty by měly používat <code>VelkaPismenaNaZacatkuSlovBezPodtrzitek</code>.

note: (itstool) path: item/p
en: Macros and constants should use <code>UPPER_CASE_WITH_UNDERSCORES</code>.
cs: Makra a konstanty by měly používat <code>VELKA_PISMENA_S_PODTRZITKY</code>.

note: (itstool) path: item/p
en: All symbols should be prefixed with a short (2–4 characters) version of the namespace. This is shortened purely for ease of typing, but should still be unique.
cs: Všechny symboly by měly mít prefix s krátkou (2 až 4 písmennou) verzí jmenného prostoru. To je dostatečně krátké pro snadné psaní, ale stále by to mělo být jedinečné.

note: (itstool) path: item/p
en: All methods of a class should also be prefixed with the class name.
cs: Také názvy všech metody třídy by měly mít na začátku připojen název třídy.

note: (itstool) path: section/p
en: Additionally, public headers should be included from a subdirectory, effectively namespacing the header files. For example, instead of <code>#include &lt;abc.h&gt;</code>, a project should allow its users to use <code>#include &lt;namespace/abc.h&gt;</code>.
cs: Navíc by veřejné hlavičkové soubory měly být vkládány z podsložky, které pro ně fakticky vytvoří jmenný prostor. Například místo <code>#include &lt;abc.h&gt;</code> by měl projekt svým uživatelům umožnit použít <code>#include &lt;namespace/abc.h&gt;</code>.

note: (itstool) path: section/p
en: Some projects namespace their headers within this subdirectory — for example, <code>#include &lt;namespace/ns-abc.h&gt;</code> instead of <code>#include &lt;namespace/abc.h&gt;</code>. This is redundant, but harmless.
cs: Některé projekty připojují jmenný prostor k hlavičkovým souborům v rámci podsložky, například <code>#include &lt;namespace/ns-abc.h&gt;</code> namísto <code>#include &lt;namespace/abc.h&gt;</code>. Dochází tak ke zdvojení, ale ničemu to nevadí.

note: (itstool) path: section/p
en: For example, for a project called ‘Walbottle’, the short namespace ‘Wbl’ would be chosen. If it has a ‘schema’ class and a ‘writer’ class, it would install headers:
cs: Například pro projekt s názvem „Walbottle“ by šel zvolit zkrácený název pro jmenný prostor „Wbl“. Když bude mít třídu „schema“ a třídu „writer“, instalovaly by se hlavičkové soubory:

note: (itstool) path: section/p
en: (The use of <var>$API_MAJOR</var> above is for <link xref="parallel-installability">parallel installability</link>.)
cs: (Použití <var>$API_MAJOR</var> výše je z důvodu <link xref="parallel-installability">možnosti souběžné instalace</link>.)

note: (itstool) path: section/p
en: For the schema class, the following symbols would be exported (amongst others), following GObject conventions:
cs: Pro třídu schématu by měly být exportovány následující symboly (mimo jiné) a dodržet při tom zvyklosti pro GObject:

note: (itstool) path: item/p
en: <code>WblSchema</code> structure
cs: Struktura <code>WblSchema</code>

note: (itstool) path: item/p
en: <code>WblSchemaClass</code> structure
cs: Struktura <code>WblSchemaClass</code>

note: (itstool) path: item/p
en: <code>WBL_TYPE_SCHEMA</code> macro
cs: Makro <code>WBL_TYPE_SCHEMA</code>

note: (itstool) path: item/p
en: <code>WBL_IS_SCHEMA</code> macro
cs: Makro <code>WBL_IS_SCHEMA</code>

note: (itstool) path: item/p
en: <code>wbl_schema_get_type</code> function
cs: Funkce <code>wbl_schema_get_type</code>

note: (itstool) path: item/p
en: <code>wbl_schema_new</code> function
cs: Funkce <code>wbl_schema_new</code>

note: (itstool) path: item/p
en: <code>wbl_schema_load_from_data</code> function
cs: Funkce <code>wbl_schema_load_from_data</code>

note: (itstool) path: info/desc
en: Writing libraries to be future proof through parallel installation
cs: Jak psát knihovny, aby v budoucnu šly instalovat souběžně různé verze

note: (itstool) path: page/title
en: Parallel Installability
cs: Souběžná instalace

note: (itstool) path: synopsis/p
en: If two packages can be parallel installed, then they have no filenames in common, and people developing against the package always compile against the version they expected. This applies to daemons, utility programs and configuration files as it does to header files and library binaries.
cs: Pokud mohou být dva balíčky nainstalovány souběžně, nesmí mít společné názvy souborů a lidé provádějící vývoj vůči balíčku vždy kompilují vůči očekávané verzi. Pro démony, pomocné programy a konfigurační soubory to platí úplně stejně, jako pro hlavičkové soubory a binární knihovny.

note: (itstool) path: item/p
en: Ensure all versions of a library are parallel installable. (<link xref="#justification"/>)
cs: Zajistěte, aby všechny verze knihoven šly nainstalovat vedle sebe. (<link xref="#justification"/>)

note: (itstool) path: item/p
en: Version all files installed by a library. (<link xref="#solution"/>)
cs: Všem souborům instalovaným knihovnou přidělte číslo verze. (<link xref="#solution"/>)

note: (itstool) path: item/p
en: Keep package version numbers separate from soname or libtool version numbers. Be clear which part of the package version number changes with the API. (<link xref="#version-numbers"/>)
cs: Udržujte číslo verze balíčku oddělené od názvu souboru s knihovnou nebo čísla verze libtool. Je pak jasnější, která část čísla verze balíčku se mění s API. (<link xref="#version-numbers"/>)

note: (itstool) path: item/p
en: Install C header files to <file><var>$(includedir)</var>/lib<var>library</var>-<var>version</var>/<var>library</var>/</file>. (<link xref="#header-files"/>)
cs: Nainstalujte hlavičkové soubory C do <file><var>$(includedir)</var>/lib<var>library</var>-<var>version</var>/<var>library</var>/</file>. (<link xref="#header-files"/>)

note: (itstool) path: item/p
en: Install library binaries to <file><var>$(libdir)</var>/lib<var>library</var>-<var>version</var>.so.<var>soname</var></file>. (<link xref="#libraries"/>)
cs: Nainstalujte spustitelné soubory knihovny do <file><var>$(libdir)</var>/lib<var>library</var>-<var>version</var>.so.<var>soname</var></file>. (<link xref="#libraries"/>)

note: (itstool) path: item/p
en: Install pkg-config files to <file><var>$(libdir)</var>/pkgconfig/<var>library</var>-<var>version</var>.pc</file>. (<link xref="#pkg-config"/>)
cs: Nainstalujte soubory pkg-config do <file><var>$(libdir)</var>/pkgconfig/<var>library</var>-<var>version</var>.pc</file>. (<link xref="#pkg-config"/>)

note: (itstool) path: item/p
en: Make configuration files forwards and backwards compatible, or install them to <file><var>$(sysconfdir)</var>/<var>library</var>-<var>version</var>/</file>. (<link xref="#configuration-files"/>)
cs: U souborů s nastavením zajistěte zpětnou a dopřednou kompatibilitu nebo je instalujte do <file><var>$(sysconfdir)</var>/<var>knihovna</var>-<var>verze</var>/</file>. (<link xref="#configuration-files"/>)

note: (itstool) path: item/p
en: Set <code>GETTEXT_PACKAGE</code> to <code><var>library</var>-<var>version</var></code>. (<link xref="#gettext"/>)
cs: Nastavte <code>GETTEXT_PACKAGE</code> na <code><var>library</var>-<var>version</var></code>. (<link xref="#gettext"/>)

note: (itstool) path: item/p
en: Include a version number in all D-Bus interface names, service names and object paths. For example: <code>org.domain.<var>Library</var><var>Version</var>.<var>Interface</var></code>, <code>org.domain.<var>Library</var><var>Version</var></code> and <code>/org/domain/<var>Library</var><var>Version</var>/</code>. (<link xref="#dbus"/>)
cs: Do všech názvů rozhraní D-Bus, názvů služeb a cest k objektům zahrňte číslo verze. Například: <code>org.domain.<var>Knihovna</var><var>Verze</var>.<var>Rozhraní</var></code>, <code>org.domain.<var>Knihovna</var><var>Verze</var></code> a <code>/org/domain/<var>Knihovna</var><var>Verze</var>/</code>. (<link xref="#dbus"/>)

note: (itstool) path: item/p
en: Install daemon binaries to <file><var>$(libexecdir)</var>/<var>library</var>-daemon-<var>version</var></file>. (<link xref="#programs"/>)
cs: Nainstalujte spustitelné soubory démonů do <file><var>$(libexecdir)</var>/<var>library</var>-daemon-<var>version</var></file>. (<link xref="#programs"/>)

note: (itstool) path: item/p
en: Install utility binaries to <file><var>$(bindir)</var>/<var>library</var>-utility-<var>version</var></file> and install symbolic links to <file><var>$(bindir)</var>/<var>library</var>-utility</file>. (<link xref="#programs"/>)
cs: Spustitelné soubory pomůcek instalujte do <file><var>$(bindir)</var>/<var>knihovna</var>-utility-<var>verze</var></file> a symbolické odkazy do <file><var>$(bindir)</var>/<var>knihovna</var>-utility</file>. (<link xref="#programs"/>)

note: (itstool) path: section/title
en: Justification
cs: Odůvodnění

note: (itstool) path: section/p
en: All public libraries should be designed to be parallel installed to ease API breaks later in the life of the library. If a library is used by multiple projects, and wants to break API, either all of the projects must be ported to the new API in parallel, or some of them will no longer be installable at the same time as the others, due to depending on conflicting versions of this library.
cs: Všechny veřejné knihovny by měly být navržené tak, aby je šlo instalovat souběžně ve více verzích, kvůli jednoduššímu pozdějšímu porušení API po dobu existence knihovny. Pokud je knihovna používána více projekty a chcete porušit API, buď musí projekty naráz přejít na nové API, nebo některé z nich již nebude nadále možné nainstalovat souběžně s ostatními, protože závisí na konfliktní verzi této knihovny.

note: (itstool) path: section/p
en: This is unmaintainable, and asking all the projects to port to a new API at the same time is hard to organize and demoralizing, as most API breaks do not bring large new features which would motivate porting.
cs: To komplikuje správu a žádat pro všech projektech, aby naráz přesly na novou verzi API je organizačně náročné a demoralizující, protože většina porušení API nepřinese mnoho nových funkcí, které by motivovaly k přechodu.

note: (itstool) path: section/p
en: The solution is to ensure that all libraries are parallel installable, allowing the old and new versions of the API to be installed and compiled against at the same time, without conflicts. Building in support for this kind of parallel installation is much easier to do at the start of a project than it is to do retroactively.
cs: Řešením je zajistit, aby šly všechny verze knihoven nainstalovat naráz, takže staré i nové verze API budou nainstalované a aplikace zkompilované vůči nim souběžně, bez konfliktů. Vestavění podpory pro tento druh souběžné instalace je mnohem jednodušší udělat na začátku projektu, než to dělat zpětně.

note: (itstool) path: section/p
en: This eliminates the ‘chicken and egg’ problem of porting a collection of applications from one version of a library to the next, and makes breaking API a lot simpler for library maintainers, which can allow for more rapid iteration and development of new features if they desire.
cs: Tím se odstraní problém „slepice nebo vejce“ při přechodu celé sady aplikací z jedné verze knihovny na novější a pro správce knihovny si tím velmi zjednoduší porušení API, takže mohou při vývoji mnohem rychleji reagovat na přání nových funkcí.

note: (itstool) path: section/p
en: The alternative, and equally valid, solution is for the library to never break API — the approach taken by <code>libc</code>.
cs: Jiným a rovněž platným řešením pro knihovny je, nikdy nenarušovat API — tímto se řídí <code>libc</code>.

note: (itstool) path: section/title
en: Solution
cs: Řešení

note: (itstool) path: section/p
en: The solution to the problem is essentially to rename the library, and in most cases the nicest way to do so is to include the version number in the path of every file it installs. This means multiple versions of the library can be installed at the same time.
cs: Řešením problému v podstatě je přejmenovat knihovnu a ve většině případů je nejhezčím způsobem, jak to udělat, vložit do cesty ke každému instalovanému souboru číslo verze. Díky tomu může být naráz nainstalováno více verzí knihovny.

note: (itstool) path: section/p
en: For example, say that library <code>Foo</code> traditionally installs these files:
cs: Kupříkladu řekněme, že knihovna <code>Foo</code> tradičně instaluje tyto soubory:

note: (itstool) path: section/p
en: You might modify <code>Foo</code> version 4 to install these files instead:
cs: Můžete změnit verzi 4 knihovny <code>Foo</code>, aby místo toho instalovala tyto soubory:

note: (itstool) path: section/p
en: It could then be parallel installed with version 5:
cs: Pak by mohly být nainstalovány souběžně s verzí 5:

note: (itstool) path: section/p
en: This is easily supported using <link href="http://www.freedesktop.org/wiki/Software/pkg-config/"> <cmd>pkg-config</cmd></link>: <file>foo-4.pc</file> would add <file>/usr/include/foo-4</file> to the include path and <file>libfoo-4.so</file> to the list of libraries to link; <file>foo-5.pc</file> would add <file>/usr/include/foo-5</file> and <file>libfoo-5.so</file>.
cs: To je jednoduše podporováno pomocí <link href="http://www.freedesktop.org/wiki/Software/pkg-config/"><cmd>pkg-config</cmd></link>: <file>foo-4.pc</file> by přidal do cesty <file>/usr/include/foo-4</file> a do seznamu knihoven odkaz <file>libfoo-4.so</file>; <file>foo-5.pc</file> by přidal <file>/usr/include/foo-5</file> a <file>libfoo-5.so</file>.

note: (itstool) path: section/title
en: Version Numbers
cs: Čísla verzí

note: (itstool) path: section/p
en: The version number that goes in filenames is an <em>ABI/API</em> version. It should not be the full version number of your package — just the part which signifies an API break. If using the standard <code><var>major</var>.<var>minor</var>.<var>micro</var></code> scheme for project versioning, the API version is typically the major version number.
cs: Číslo verze které se zahrne do názvu souboru je veze <em>ABI/API</em>. Nemělo by jít o celé číslo verze balíčku, jen o část, která významěmně porušuje API. Pokud používáte pro číslování verzí projektu standartní schéma <code><var>hlavní</var>.<var>vedlejší</var>.<var>setinkové</var></code>, je verzí API typicky hlavní číslo verze.

note: (itstool) path: section/p
en: Minor releases (typically where API is added but <em>not</em> changed or removed) and micro releases (typically bug fixes) do not affect <link xref="api-stability">API backwards compatibility</link> so do not require moving all the files.
cs: Vedlejší vydání (typicky, když je přidáno API, ale <em>není</em> změněno nebo odebráno) a setinková vydání (typicky opravy chyb) neovlivňují <link xref="api-stability">zpětnou kompatibilitu API</link>, takže nevyžadují přesun všech souborů.

note: (itstool) path: section/p
en: The examples in the following sections assume that the API version and soname are exported from <file>configure.ac</file> using the following code:
cs: Příklady v následujícím oddíle předpokládají, že verze API a název souboru s knihovnou jsou exportovány z <file>configure.ac</file> pomocí následujícího kódu:

note: (itstool) path: listing/title
en: API Versioning in Autoconf
cs: Číslování verzí API v Autoconf

note: (itstool) path: listing/desc
en: Code to export the API version and soname from <file>configure.ac</file>
cs: Kód pro export verze API a názvu souboru s knihovnou z <file>configure.ac</file>

note: (itstool) path: listing/code
en: # Before making a release, the <var>LIBRARY</var>_LT_VERSION string should be modified.
    # The string is of the form c:r:a. Follow these instructions sequentially:
    #
    #  1. If the library source code has changed at all since the last update,
    #     then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
    #  2. If any interfaces have been added, removed, or changed since the last update,
    #     increment current, and set revision to 0.
    #  3. If any interfaces have been added since the last public release,
    #     then increment age.
    #  4. If any interfaces have been removed or changed since the last public release,
    #     then set age to 0.
    AC_SUBST([<var>LIBRARY</var>_LT_VERSION],[1:0:0])
    
    AC_SUBST([<var>LIBRARY</var>_API_VERSION],[4])
cs: # Před vydáním by se měl upravit řetězec <var>KNIHOVNA</var>_LT_VERSION, který
    # je ve formě a:r:v (aktuální:revize:věk). Postupujte podle následujících bodů:
    #
    #   1. Když od poslední aktualizace došlo ke změně zdrojového kódu knihovny
    #      jako celku, zvyšte revizi („a:r:v“ se změní na „a:r+1:v“).
    #   2. Když bylo od poslední aktualizace přidáno, odebráno nebo změněno
    #      rozhraní, zvyšte aktuální a revizi nastavte na 0.
    #   3. Když bylo od posledního veřejného vydání přidáno rozhraní, zvyšte věk.
    #   4. Když bylo od posledního veřejného vydání odebráno nebo změněno 
    #      rozhraní, nastavte věk na 0.
    AC_SUBST([<var>KNIHOVNA</var>_LT_VERSION],[1:0:0])
    
    AC_SUBST([<var>KNIHOVNA</var>_API_VERSION],[4])

note: (itstool) path: section/title
en: C Header Files
cs: Hlavičkové soubory C

note: (itstool) path: section/p
en: Header files should always be installed in a versioned subdirectory that requires an <cmd>-I</cmd> flag to the C compiler. For example, if my header is <file>foo.h</file>, and applications do this:
cs: Hlavičkové soubory by vždy měly být nainstalovány v podsložce s číslem verze, kterou požaduje přepínač <cmd>-I</cmd> pro kompilátor jazyka C. Například, když je hlavičkový soubor <file>foo.h</file> a aplikace udělá následující:

note: (itstool) path: section/p
en: then I should install these files:
cs: pak by měly být nainstalovány tyto soubory:

note: (itstool) path: section/p
en: Applications should pass the flag <cmd>-I/usr/include/foo-4</cmd> or <cmd>-I/usr/include/foo-5</cmd> to the C compiler. Again, this is facilitated by using <cmd>pkg-config</cmd>.
cs: Aplikace by měla kompilátoru jazyka C předat přepínač <cmd>-I/usr/include/foo-4</cmd> nebo <cmd>-I/usr/include/foo-5</cmd>. Jak již bylo několikrát řečeno, to vše vám může usnadnit <cmd>pkg-config</cmd>.

note: (itstool) path: section/p
en: Note the extra <file>foo/</file> subdirectory. This namespaces the <code mime="text/x-csrc">#include</code> to avoid file naming collisions with other libraries. For example, if two different libraries install headers called <file>utils.h</file>, which one gets included when you use <code mime="text/x-csrc">#include &lt;utils.h&gt;</code>?
cs: Všimněte si zvláštní podsložky <file>foo/</file>. Funguje jako jmenný prostor pro <code mime="text/x-csrc">#include</code>, aby se předešlo kolizi názvů s jinými knihovnami. Když například dvě různé knihovny nainstalují každá hlavičkový soubor s názvem <file>utils.h</file>, který se ve skutečnosti vloží, když použijete kód <code mime="text/x-csrc">#include &lt;utils.h&gt;</code>?

note: (itstool) path: section/p
en: There’s some temptation to keep one of the header files outside of any subdirectory:
cs: Existuje pokušení ponechat jeden z hlavičkových souborů mimo kteroukoliv podsložku:

note: (itstool) path: section/p
en: The problem there is that users are always accidentally getting the wrong header, since <cmd>-I/usr/include</cmd> seems to find its way onto compile command lines with some regularity. If you must do this, at least add a check to the library that detects applications using the wrong header file when the library is initialized.
cs: Problém je v tom, že uživatel určitě vždycky omylem použije nesprávnou hlavičku, protože <cmd>-I/usr/include</cmd> si při kompilaci vždy najde nějakou cestičku do příkazového řádku. Pokud to musíte udělat, minimálně do knihovny přidejte kontrolu, která při inicializaci knihovny objeví aplikaci používající nesprávný hlavičkový soubor.

note: (itstool) path: section/p
en: Versioned header files can be installed from automake using the following code:
cs: Hlavičkové soubory s číslem verze mohou být instalovány z automake pomocí následujícího kódu:

note: (itstool) path: listing/title
en: Header Files in Automake
cs: Hlavičkové soubory v Automake

note: (itstool) path: listing/desc
en: Code to install versioned header files from <file>Makefile.am</file>
cs: Kód pro instalaci hlavičkových souborů s číslem verze z <file>Makefile.am</file>

note: (itstool) path: section/p
en: As well as correct versioning, all APIs in installed headers should be <link xref="namespacing">namespaced correctly</link>.
cs: Kromě správného číslování verzí by měla mít všechna API v instalovaných hlavičkových souborech <link xref="namespacing">správný jmenný prostor</link>.

note: (itstool) path: section/title
en: Libraries
cs: Knihovny

note: (itstool) path: section/p
en: Library object files should have a versioned name. For example:
cs: Objektové soubory knihovny by měly mít názvy s číslem verze. Například:

note: (itstool) path: section/p
en: This allows applications to get exactly the one they want at compile time, and ensures that versions 4 and 5 have no files in common.
cs: To umožňuje aplikacím získat při kompilaci právě tu, kterou chtějí a zajistí to, že verze 4 a 5 nemají žádné soubory společné.

note: (itstool) path: section/p
en: Versioned libraries can be built and installed from automake using the following code:
cs: Knihovny s číslem verze mohou být sestaveny a nainstalovány z automake pomocí následujícího kódu:

note: (itstool) path: listing/title
en: Libraries in Automake
cs: Knihovny v Automake

note: (itstool) path: listing/desc
en: Code to build and install versioned libraries from <file>Makefile.am</file>
cs: Kód pro sestavení a instalaci knihoven s číslem verze z <file>Makefile.am</file>

note: (itstool) path: listing/code
en: lib_LTLIBRARIES = lib<var>library</var>/lib<var>library</var>-@<var>LIBRARY</var>_API_VERSION@.la
    
    lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_SOURCES = \
    	$(private_headers) \
    	$(<var>library</var>_sources) \
    	$(NULL)
    lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_CPPFLAGS = …
    lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_CFLAGS = …
    lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_LIBADD = …
    lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_LDFLAGS = \
    	-version-info $(<var>LIBRARY</var>_LT_VERSION) \
    	$(AM_LDFLAGS) \
    	$(NULL)
cs: lib_LTLIBRARIES = lib<var>knihovna</var>/lib<var>knihovna</var>-@<var>KNIHOVNA</var>_API_VERSION@.la
    
    lib<var>knihovna</var>_lib<var>knihovna</var>_@<var>KNIHOVNA</var>_API_VERSION@_la_SOURCES = \
    	$(private_headers) \
    	$(<var>knihovna</var>_sources) \
    	$(NULL)
    lib<var>knihovna</var>_lib<var>knihovna</var>_@<var>KNIHOVNA</var>_API_VERSION@_la_CPPFLAGS = …
    lib<var>knihovna</var>_lib<var>knihovna</var>_@<var>KNIHOVNA</var>_API_VERSION@_la_CFLAGS = …
    lib<var>knihovna</var>_lib<var>knihovna</var>_@<var>KNIHOVNA</var>_API_VERSION@_la_LIBADD = …
    lib<var>knihovna</var>_lib<var>knihovna</var>_@<var>KNIHOVNA</var>_API_VERSION@_la_LDFLAGS = \
    	-version-info $(<var>KNIHOVNA</var>_LT_VERSION) \
    	$(AM_LDFLAGS) \
    	$(NULL)

note: (itstool) path: section/title
en: Library sonames
cs: Názvy souborů s knihovnami

note: (itstool) path: section/p
en: Library sonames (also known as libtool version numbers) only address the problem of runtime linking previously-compiled applications. They don’t address the issue of compiling applications that require a previous version, and they don’t address anything other than libraries.
cs: Názvy souborů s knihovnami (známé též jako soname nebo číslování verzí libtool) se zaměřují jen na problém linkování dříve přeložených aplikací za běhu. Neřeší záležitosti okolo kompilace aplikací, které požadují dřívější verzi, a ani nic jiného okolo knihoven.

note: (itstool) path: section/p
en: For this reason, sonames should be used, but <em>in addition</em> to versioned names for libraries. The two solutions address different problems.
cs: Z toho důvodu byste ještě <em>navíc</em> měli používat pro knihovny názvy s číslováním verzi. Každá z těchto věcí cílí na jiný problém.

note: (itstool) path: section/title
en: pkg-config Files
cs: Soubory pkg-config

note: (itstool) path: section/p
en: pkg-config files should have a versioned name. For example:
cs: Soubory pkg-config by měly mít názvy s číslem verze. Například:

note: (itstool) path: section/p
en: Since each pkg-config file contains versioned information about the library name and include paths, any project which depends on the library should be able to switch from one version to another simply by changing their pkg-config check from <file>foo-4</file> to <file>foo-5</file> (and doing any necessary API porting).
cs: Protože každý soubor pkg-config obsahuje informace o verzi názvu knihovny včetně cesty, měl by být kterýkoliv projekt, který závisí na knihovně, schopen se přepnout z jedné verze na jinou prostou změnou kontroly ve svém pkg-config z <file>neco-4</file> na <file>neco-5</file> (a provedením příslušného přechodu v API).

note: (itstool) path: section/p
en: Versioned pkg-config files can be installed from autoconf and automake using the following code:
cs: Soubory pkg-config s rozlišením verze mohou být instalovány z autoconf a automake pomocí následujícího kódu:

note: (itstool) path: listing/title
en: pkg-config Files in Autoconf and Automake
cs: Soubory pkg-config v Autoconf a Automake

note: (itstool) path: listing/desc
en: Code to install versioned pkg-config files from <file>configure.ac</file> and <file>Makefile.am</file>
cs: Kód pro instalaci souborů pkg-config s rozlišením verze z <file>configure.ac</file> a <file>Makefile.am</file>

note: (itstool) path: listing/code
en: AC_CONFIG_FILES([
    lib<var>library</var>/<var>library</var>-$<var>LIBRARY</var>_API_VERSION.pc:lib<var>library</var>/<var>library</var>.pc.in
    ],[],
    [<var>LIBRARY</var>_API_VERSION='$<var>LIBRARY</var>_API_VERSION'])
cs: AC_CONFIG_FILES([
    lib<var>knihovna</var>/<var>knihovna</var>-$<var>KNIHOVNA</var>_API_VERSION.pc:lib<var>knihovna</var>/<var>knihovna</var>.pc.in
    ],[],
    [<var>KNIHOVNA</var>_API_VERSION='$<var>KNIHOVNA</var>_API_VERSION'])

note: (itstool) path: listing/code
en: # Note that the template file is called <var>library</var>.pc.in, but generates a
    # versioned .pc file using some magic in AC_CONFIG_FILES.
    pkgconfigdir = $(libdir)/pkgconfig
    pkgconfig_DATA = lib<var>library</var>/<var>library</var>-$(<var>LIBRARY</var>_API_VERSION).pc
    
    DISTCLEANFILES += $(pkgconfig_DATA)
    EXTRA_DIST += lib<var>library</var>/<var>library</var>.pc.in
cs: # Všimněte si, že soubor s šablonou se nazývá <var>library</var>.pc.in, ale generuje se
    # soubor .pc s číslem verze pomocí stejné magie, jako v AC_CONFIG_FILES.
    pkgconfigdir = $(libdir)/pkgconfig
    pkgconfig_DATA = lib<var>knihovna</var>/<var>knihovna</var>-$(<var>KNIHOVNA</var>_API_VERSION).pc
    
    DISTCLEANFILES += $(pkgconfig_DATA)
    EXTRA_DIST += lib<var>knihovna</var>/<var>knihovna</var>.pc.in

note: (itstool) path: section/title
en: Configuration Files
cs: Soubory s nastavením

note: (itstool) path: section/p
en: From a user standpoint, the best approach to configuration files is to keep the format both <link xref="api-stability">forward and backward compatible</link> (both library versions understand exactly the same configuration file syntax and semantics). Then the same configuration file can be used for all versions of the library, and no versioning is needed on the configuration file itself.
cs: Z hlediska uživatele je nejlepším přístupem k souborům s nastavením udržovat formát <link xref="api-stability">dopředně i zpětně kompatibilní</link> (obě verze knihovny rozumí právě té stejné syntaxi a sémantice souboru s nastavením). Pak lze použít ten samý soubor s nastavením pro všechny verze knihovny a není potřeba žádné číslování verzí u souborů s nastavením.

note: (itstool) path: section/p
en: If you can’t do that, the configuration files should simply be renamed, and users will have to configure each version of the library separately.
cs: Pokud to ale dodržet nejde, měly by být soubory s nastavením jednoduše přejmenovány a uživatel musí nastavit každou verzi knihovny zvlášť.

note: (itstool) path: section/title
en: Gettext Translations
cs: Překlady pomocí Gettext

note: (itstool) path: section/p
en: If you use gettext for translations in combination with autoconf and automake, normally things are set up to install the translations to <file>/usr/share/locale/<var>lang</var>/LC_MESSAGES/<var>package</var></file>. You’ll need to change <var>package</var>. The convention used in GNOME is to put this in <file>configure.ac</file>:
cs: Jestli používáte pro překlady gettext v kombinaci s autoconf a automake, je normální postup nainstalovat překlady do <file>/usr/share/locale/<var>jazyk</var>/LC_MESSAGES/<var>balíček</var></file>. Údaj <var>baliček</var> musíte změnit na správný název. Podle zvyklostí používaných v GNOME se to celé vloží do <file>configure.ac</file>:

note: (itstool) path: section/p
en: Then use <code>GETTEXT_PACKAGE</code> as the package name to pass to <code mime="text/x-csrc">bindtextdomain()</code>, <code mime="text/x-csrc">textdomain()</code>, and <code mime="text/x-csrc">dgettext()</code>.
cs: Pak použijte <code>GETTEXT_PACKAGE</code> jako název balíčku předaný do <code mime="text/x-csrc">bindtextdomain()</code>, <code mime="text/x-csrc">textdomain()</code> a <code mime="text/x-csrc">dgettext()</code>.

note: (itstool) path: section/title
en: D-Bus Interfaces
cs: Rozhraní D-Bus

note: (itstool) path: section/p
en: A D-Bus interface is another form of API, similar to a C API except that resolution of the version is done at runtime rather than compile time. Versioning D-Bus interfaces is otherwise no different to C APIs: version numbers must be included in interface names, service names and object paths.
cs: Rozhraní D-Bus je další formou API a podobá se API v C s tím rozdílem, že rozlišení verze se neprovádí při kompilaci, ale za běhu. Číslování verzí rozhraní D-Bus se jinak od API v C nijak neliší: čísla verzí musí být zahrnuta v názvech rozhraní, názvech služeb a v cestách k objektům.

note: (itstool) path: section/p
en: For example, for a service <code>org.example.Foo</code> exposing interfaces <code>A</code> and <code>B</code> on objects <code>Controller</code> and <code>Client</code>, versions 4 and 5 of the D-Bus API would look like this:
cs: Například pro službu <code>org.example.Foo</code> vystavující rozhraní <code>A</code> a <code>B</code> na objektech <code>Controller</code> a <code>Client</code>, by verze 4 a 5 API pro D-Bus vypadala nějak takto:

note: (itstool) path: list/title
en: Service Names
cs: Názvy služeb

note: (itstool) path: list/title
en: Interface Names
cs: Názvy rozhraní

note: (itstool) path: list/title
en: Object Paths
cs: Cesty k objektům

note: (itstool) path: section/title
en: Programs, Daemons and Utilities
cs: Programy, démoni a pomůcky

note: (itstool) path: section/p
en: Desktop applications generally do not need to be versioned, as they are not depended on by any other modules. Daemons and utility programs, however, interact with other parts of the system and hence need versioning.
cs: Grafické aplikace obecně nepotřebují být nainstalované ve více verzích, protože na nich nezávisí další moduly. Démoni a pomocné programy ale spolupracují s dalšími částmi systému, a tak číslování verzí v názvech potřebují.

note: (itstool) path: section/p
en: Given a daemon and utility program:
cs: Mějme démona a pomocný program:

note: (itstool) path: section/p
en: these should be versioned as:
cs: Číslo verze pak mohou mít přidělené jako:

note: (itstool) path: section/p
en: You may want to install a symbolic link from <file>/usr/bin/foo-lookup-utility</file> to the recommended versioned copy of the utility, to make it more convenient for users to use.
cs: Můžete nainstalovat symbolický odkaz z <file>/usr/bin/foo-lookup-utility</file> na doporučovanou verzi kopie pomocného programu, aby se pohodlněji používal uživatelům.

note: (itstool) path: info/desc
en: Contract programming with checks on function input and output
cs: Kontraktové programování s kontrolami na vstupu a výstupu funkcí

note: (itstool) path: page/title (itstool) path: section/title
en: Pre- and Post-Conditions
cs: Úvodní a závěrečné podmínky

note: (itstool) path: section/p
en: An important part of secure coding is ensuring that incorrect data does not propagate far through code — the further some malicious input can propagate, the more code it sees, and the greater potential there is for an exploit to be possible.
cs: Důležitou zásadou bezpečného kódu je, že se nesprávná data nebudou programem dále šířit – čím dále se vadný vstup může dostat, tím větší částí kódu projde a potenciálně se zvyšuje možnost využít je k útoku.

note: (itstool) path: section/p
en: A standard way of preventing the propagation of invalid data is to check all inputs to, and outputs from, all publicly visible functions in a library or module. There are two levels of checking:
cs: Standardním způsobem předcházení šíření neplatných dat je kontrolovat všechny vstupy do a výstupy ze všech veřejně viditelných funkcí v knihovně nebo modulu. Existují dvě úrovně kontroly:

note: (itstool) path: item/title
en: Assertions
cs: Aserce

note: (itstool) path: item/p
en: Check for programmer errors and abort the program on failure.
cs: Kontrolují programové chyby a při selhání program přeruší.

note: (itstool) path: item/title
en: Validation
cs: Validace

note: (itstool) path: item/p
en: Check for invalid input and return an error gracefully on failure.
cs: Kontrolují neplatný vstup a při selhání vhodně vracejí chybu.

note: (itstool) path: section/p
en: Validation is a complex topic, and is handled using <link xref="gerror">GErrors</link>. The remainder of this section discusses pre- and post-condition assertions, which are purely for catching programmer errors. A programmer error is where a function is called in a way which is documented as disallowed. For example, if <code>NULL</code> is passed to a parameter which is documented as requiring a non-<code>NULL</code> value to be passed; or if a negative value is passed to a function which requires a positive value. Programmer errors can happen on output too — for example, returning <code>NULL</code> when it is not documented to, or not setting a GError output when it fails.
cs: Validace je náročná záležitost, která se řeší pomocí <link xref="gerror">GErrors</link>. Zbývající část tohoto oddílu rozebírá úvodní a koncové podmínky asercí, které jsou určené čistě pro odhalování chyb programátora. Programátorskou chybou je, když je funkce zavolána způsobem, který je v dokumentaci uvedený jako zakázaný. Například když je předána hodnota <code>NULL</code> v parametru, pro který je uvedeno, že vyžaduje hodnotu, která není <code>NULL</code>, nebo když je předána záporná hodnota v parametru, který vyžaduje kladnou hodnotu. Programátorské chyby mohou nastat i na výstupu, například návratová hodnota <code>NULL</code>, když není uvedená v dokumentaci, nebo když není nastaven výstup GError při selhání.

note: (itstool) path: section/p
en: Adding pre- and post-condition assertions to code is as much about ensuring the behavior of each function is correctly and completely documented as it is about adding the assertions themselves. All assertions should be documented, preferably by using the relevant <link xref="introspection">introspection annotations</link>, such as <code>(nullable)</code>.
cs: Přidání úvodních a koncových podmínek asercí do kódu je hlavně o zajištění správného chování a jeho podrobného uvedení v dokumentaci, než o vlastním přidání asercí. Všechny aserce by měly být zdokumentované, nejlépe pomocí příslušné <link xref="introspection">anotace k introspekci</link>, jako je <code>(nullable)</code>.

note: (itstool) path: section/p
en: Pre- and post-condition assertions are implemented using <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-if-fail"><code>g_return_if_fail()</code></link> and <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail"><code>g_return_val_if_fail()</code></link>.
cs: Úvodní a závěrečné podmínky asercí jsou implementovány pomocí <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-if-fail"><code>g_return_if_fail()</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Warnings-and-Assertions.html#g-return-val-if-fail"><code>g_return_val_if_fail()</code></link>.

note: (itstool) path: section/p
en: The pre-conditions should check each parameter at the start of the function, before any other code is executed (even retrieving the private data structure from a GObject, for example, since the GObject pointer could be <code>NULL</code>). The post-conditions should check the return value and any output parameters at the end of the function — this requires a single <code>return</code> statement and use of <code>goto</code> to merge other control paths into it. See <link xref="memory-management#single-path-cleanup"/> for an example.
cs: Úvodní podmínky by měly kontrolovat jednotlivé parametry hned na začátku funkce, dříve než je proveden jakýkoliv další kód (i třeba načtení privátní datové struktury z GObject, protože by například mohl mít ukazatel na GObject hodnotu <code>NULL</code>). Koncové podmínky by měly kontrolovat návratovou hodnotu a případné výstupní parametry na konci funkce, což vyžaduje jediný výraz <code>return</code> a použití příkazu <code>goto</code> pro sloučení ostatních průchodových cest do něj. Příklad viz <link xref="memory-management#single-path-cleanup"/>.

note: (itstool) path: info/desc
en: Moving computation out of the main thread into worker threads
cs: Přesun výpočtů mimo hlavní vlákno do pracovních vláken

note: (itstool) path: page/title
en: Threading
cs: Vlákna

note: (itstool) path: item/p
en: Do not use threads if at all possible. (<link xref="#when-to-use-threading"/>)
cs: Pokud je to možné, vlákna nepoužívejte (<link xref="#when-to-use-threading"/>)

note: (itstool) path: item/p
en: If threads have to be used, use <code>GTask</code> or <code>GThreadPool</code> and isolate the threaded code as much as possible. (<link xref="#using-threading"/>)
cs: Pokud vlákna použít musíte, použijte <code>GTask</code> nebo <code>GThreadPool</code> a kód vlákna izolujte co nejvíce je možné. (<link xref="#using-threading"/>)

note: (itstool) path: item/p
en: Use <code>g_thread_join()</code> to avoid leaking thread resources if using <code>GThread</code> manually. (<link xref="#using-threading"/>)
cs: Při ručním požití <code>GThread</code> používejte <code>g_thread_join()</code>, abyste předešli únikům prostředků vlákna. (<link xref="#using-threading"/>)

note: (itstool) path: item/p
en: Be careful about the <code>GMainContext</code> which code is executed in if using threads. Executing code in the wrong context can cause race conditions, or block the main loop. (<link xref="#using-threading"/>)
cs: Při použití vláken dávejte pozor, jaký kód spouštíte v <code>GMainContext</code>. Spuštění kódu v nesprávném kontextu může způsobit souběh podmínek nebo blokování hlavní smyčky. (<link xref="#using-threading"/>)

note: (itstool) path: section/title
en: When to Use Threading
cs: Kdy použít vlákna

note: (itstool) path: section/p
en: When writing projects using GLib, the default approach should be to <em style="strong">never use threads</em>. Instead, make proper use of the <link xref="main-contexts">GLib main context</link> which, through the use of <link xref="async-programming">asynchronous operations</link>, allows most blocking I/O operations to continue in the background while the main context continues to process other events. Analysis, review and debugging of threaded code becomes very hard, very quickly.
cs: Když píšete projekty s pomocí GLib, mělo by být výchozím přístupem pravidlo <em style="strong">nikdy nepoužívat vlákna</em>. Místo toho správně používejte <link xref="main-contexts">hlavní kontext GLib</link>, který, skrz použití <link xref="async-programming">asynchronních operací</link>, umožňuje většině blokujících V/V operací pokračovat na pozadí, zatímco hlavní kontext pokračuje ve zpracování dalších událostí. Analýza, kontrola a ladění programového kódu vláken se velmi rychle dokáže zvrhnout ve velmi složitou věc.

note: (itstool) path: section/p
en: Threading should only be necessary when using an external library which has blocking functions which need to be called from GLib code. If the library provides a non-blocking alternative, or one which integrates with a <link href="http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html"><code>poll()</code></link> loop, that should be used in preference. If the blocking function really must be used, a thin wrapper should be written for it to convert it to the normal <link href="https://developer.gnome.org/gio/stable/GAsyncResult.html"><code>GAsyncResult</code> style</link> of GLib asynchronous function, running the blocking operation in a worker thread.
cs: Vlákna by se měla používat jen, když je to nutné kvůli externí knihovně, která má blokující funkce, které potřebujete volat z kódu GLib. Jestliže knihovna poskytuje neblokující variantu, nebo nějakou integrovanou se smyčkou <link href="http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html"><code>poll()</code></link>, měli byste takové variantě dát přednost. Pokud musíte opravdu použít blokující funkci, měli byste k ní napsat tenký obalující kód, který ji převede na běžnou asynchronní funkci ve <link href="https://developer.gnome.org/gio/stable/GAsyncResult.html">stylu <code>GAsyncResult</code></link> z GLib, a který spustí blokující operaci v pracovním vlákně.

note: (itstool) path: example/p
en: Should be wrapped as:
cs: By měla být obalena jako:

note: (itstool) path: example/p
en: With an implementation something like:
cs: S nějakou takovouto implementací:

note: (itstool) path: example/code
en: /* Closure for the call’s parameters. */
    typedef struct {
      void *param1;
      void *param2;
    } SomeBlockingFunctionData;
    
    static void
    some_blocking_function_data_free (SomeBlockingFunctionData *data)
    {
      free_param (data-&gt;param1);
      free_param (data-&gt;param2);
    
      g_free (data);
    }
    
    static void
    some_blocking_function_thread_cb (GTask         *task,
                                      gpointer       source_object,
                                      gpointer       task_data,
                                      GCancellable  *cancellable)
    {
      SomeBlockingFunctionData *data = task_data;
      int retval;
    
      /* Handle cancellation. */
      if (g_task_return_error_if_cancelled (task))
        {
          return;
        }
    
      /* Run the blocking function. */
      retval = some_blocking_function (data-&gt;param1, data-&gt;param2);
      g_task_return_int (task, retval);
    }
    
    void
    some_blocking_function_async (void                 *param1,
                                  void                 *param2,
                                  GCancellable         *cancellable,
                                  GAsyncReadyCallback   callback,
                                  gpointer              user_data)
    {
      GTask *task = NULL;  /* owned */
      SomeBlockingFunctionData *data = NULL;  /* owned */
    
      g_return_if_fail (validate_param (param1));
      g_return_if_fail (validate_param (param2));
      g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
    
      task = g_task_new (NULL, cancellable, callback, user_data);
      g_task_set_source_tag (task, some_blocking_function_async);
    
      /* Cancellation should be handled manually using mechanisms specific to
       * some_blocking_function(). */
      g_task_set_return_on_cancel (task, FALSE);
    
      /* Set up a closure containing the call’s parameters. Copy them to avoid
       * locking issues between the calling thread and the worker thread. */
      data = g_new0 (SomeBlockingFunctionData, 1);
      data-&gt;param1 = copy_param (param1);
      data-&gt;param2 = copy_param (param2);
    
      g_task_set_task_data (task, data, some_blocking_function_data_free);
    
      /* Run the task in a worker thread and return immediately while that continues
       * in the background. When it’s done it will call @callback in the current
       * thread default main context. */
      g_task_run_in_thread (task, some_blocking_function_thread_cb);
    
      g_object_unref (task);
    }
    
    int
    some_blocking_function_finish (GAsyncResult  *result,
                                   GError       **error)
    {
      g_return_val_if_fail (g_task_is_valid (result,
                                             some_blocking_function_async), -1);
      g_return_val_if_fail (error == NULL || *error == NULL, -1);
    
      return g_task_propagate_int (G_TASK (result), error);
    }
cs: /* Zapouzdření pro parametry volání */
    typedef struct {
      void *param1;
      void *param2;
    } SomeBlockingFunctionData;
    
    static void
    some_blocking_function_data_free (SomeBlockingFunctionData *data)
    {
      free_param (data-&gt;param1);
      free_param (data-&gt;param2);
    
      g_free (data);
    }
    
    static void
    some_blocking_function_thread_cb (GTask         *task,
                                      gpointer       source_object,
                                      gpointer       task_data,
                                      GCancellable  *cancellable)
    {
      SomeBlockingFunctionData *data = task_data;
      int retval;
    
      /* Obsluha zrušení */
      if (g_task_return_error_if_cancelled (task))
        {
          return;
        }
    
      /* Spuštění blokující funkce */
      retval = some_blocking_function (data-&gt;param1, data-&gt;param2);
      g_task_return_int (task, retval);
    }
    
    void
    some_blocking_function_async (void                 *param1,
                                  void                 *param2,
                                  GCancellable         *cancellable,
                                  GAsyncReadyCallback   callback,
                                  gpointer              user_data)
    {
      GTask *task = NULL;  /* vlastněno */
      SomeBlockingFunctionData *data = NULL;  /* vlastněno */
    
      g_return_if_fail (validate_param (param1));
      g_return_if_fail (validate_param (param2));
      g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
    
      task = g_task_new (NULL, cancellable, callback, user_data);
      g_task_set_source_tag (task, some_blocking_function_async);
    
      /* Zrušení by mělo být obslouženo ručně pomocí mechanizmu určeného
       * konkrétně pro some_blocking_function(). */
      g_task_set_return_on_cancel (task, FALSE);
    
      /* Nastaví zapouzdření obsahující parametry volání. Zkopíruje je, aby se
       * předešlo problémům se zamykáním mezi volajícím vláknem a pracovním vláknem */
      data = g_new0 (SomeBlockingFunctionData, 1);
      data-&gt;param1 = copy_param (param1);
      data-&gt;param2 = copy_param (param2);
    
      g_task_set_task_data (task, data, some_blocking_function_data_free);
    
      /* Spustí úlohu v pracovním vlákně a ihned se vrátí, zatímco zpracování
       * pokračuje na pozadí. Když je dokončeno, je zavolána funkce @callback
       * ve výchozím hlavním kontextu aktuálního vlákna */
      g_task_run_in_thread (task, some_blocking_function_thread_cb);
    
      g_object_unref (task);
    }
    
    int
    some_blocking_function_finish (GAsyncResult  *result,
                                   GError       **error)
    {
      g_return_val_if_fail (g_task_is_valid (result,
                                             some_blocking_function_async), -1);
      g_return_val_if_fail (error == NULL || *error == NULL, -1);
    
      return g_task_propagate_int (G_TASK (result), error);
    }

note: (itstool) path: example/p
en: See the <link href="https://developer.gnome.org/gio/stable/GAsyncResult.html"><code>GAsyncResult</code> documentation</link> for more details. A simple way to implement the worker thread is to use <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> and <link href="https://developer.gnome.org/gio/stable/GTask.html#g-task-run-in-thread"><code>g_task_run_in_thread()</code></link>. (See also: <link xref="main-contexts#gtask"/>.)
cs: Další podrobnosti viz <link href="https://developer.gnome.org/gio/stable/GAsyncResult.html">dokumentace k <code>GAsyncResult</code></link>. Jednoduchým způsobem, jak implementovat pracovní vlákno, je <link href="https://developer.gnome.org/gio/stable/GTask.html"><code>GTask</code></link> a <link href="https://developer.gnome.org/gio/stable/GTask.html#g-task-run-in-thread"><code>g_task_run_in_thread()</code></link>. (Viz také <link xref="main-contexts#gtask"/>.)

note: (itstool) path: section/title
en: Using Threading
cs: Používání vláken

note: (itstool) path: section/p
en: If <code>GTask</code> is not suitable for writing the worker thread, a more low-level approach must be used. This should be considered very carefully, as it is very easy to get threading code wrong in ways which will unpredictably cause bugs at runtime, cause deadlocks, or consume too many resources and terminate the program.
cs: Pokud není pro napsání pracovního vlákna použitelný <code>GTask</code>, musí být použit přístup na nižší úrovni. To ale hodně dobře zvažte, protože je velmi snadné napsat kód vlákna nesprávným způsobem, který způsobí za běhu nepředvidatelné chyby, nekonečné zámky nebo spotřebu přílišného množství prostředků a ukončení programu.

note: (itstool) path: section/p
en: A full manual on writing threaded code is beyond the scope of this document, but here are a number of guidelines to follow which should reduce the potential for bugs in threading code. The overriding principle is to reduce the amount of code and data which can be affected by threading — for example, reducing the number of threads, the complexity of worker thread implementation, and the amount of data shared between threads.
cs: Kompletní návod pro psaní vláken je mimo rozsah tohoto dokumentu, ale existuje řada dalších příruček, podle kterých se můžete řídit, abyste omezili vznik potenciálních chyb v kódu vlákna. Obecným principem je omezit množství kódu a dat, které budou vláknem ovlivněny. Například omezením počtu vláken, složitosti implementace pracovního vlákna a množství dat sdílených mezi vlákny.

note: (itstool) path: item/p
en: Use <link href="https://developer.gnome.org/glib/stable/glib-Thread-Pools.html"><code>GThreadPool</code></link> instead of manually creating <link href="https://developer.gnome.org/glib/stable/glib-Threads.html"><code>GThread</code>s</link> if possible. <code>GThreadPool</code> supports a work queue, limits on the number of spawned threads, and automatically joins finished threads so they are not leaked.
cs: Pokud je to možné, použijte místo ručního vytváření svých <link href="https://developer.gnome.org/glib/stable/glib-Threads.html"><code>GThread</code></link> třídu <link href="https://developer.gnome.org/glib/stable/glib-Thread-Pools.html"><code>GThreadPool</code></link>. <code>GThreadPool</code> podporuje pracovní fronty, omezení počtu spuštěných vláken a automatické sloučení dokončených vláken, takže nedochází k jejich úniku.

note: (itstool) path: item/p
en: If it is not possible to use a <code>GThreadPool</code> (which is rarely the case):
cs: Kdy není možné použít <code>GThreadPool</code> (což je zřídkavý případ):

note: (itstool) path: item/p
en: Use <link href="https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-try-new"><code>g_thread_try_new()</code></link> to spawn threads, instead of <link href="https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-new"><code>g_thread_new()</code></link>, so errors due to the system running out of threads can be handled gracefully rather than unconditionally aborting the program.
cs: Použijte ke spuštění vlákna <link href="https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-try-new"><code>g_thread_try_new()</code></link> namísto <link href="https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-new"><code>g_thread_new()</code></link>, a chyby způsobené vybočením z vlákna pak můžete skvěle ošetřit, místo aby došlo k nepodmíněnému přerušení programu.

note: (itstool) path: item/p
en: Explicitly join threads using <link href="https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-join"><code>g_thread_join()</code></link> to avoid leaking the thread resources.
cs: Výslovně spojte vlákna pomocí <link href="https://developer.gnome.org/glib/stable/glib-Threads.html#g-thread-join"><code>g_thread_join()</code></link>, abyste předešli úniku prostředků vlákna.

note: (itstool) path: item/p
en: Use message passing to transfer data between threads, rather than manual locking with mutexes. <code>GThreadPool</code> explicitly supports this with <link href="https://developer.gnome.org/glib/stable/glib-Thread-Pools.html#g-thread-pool-push"><code>g_thread_pool_push()</code></link>.
cs: Místo ručního zamykání pomocí mutexů použijte raději předávání zpráv do dat přenášených mezi vlákny. <code>GThreadPool</code> to vyloženě podporuje pomocí <link href="https://developer.gnome.org/glib/stable/glib-Thread-Pools.html#g-thread-pool-push"><code>g_thread_pool_push()</code></link>.

note: (itstool) path: item/p
en: If mutexes must be used:
cs: Když se musí použít mutexy:

note: (itstool) path: item/p
en: Isolate threading code as much as possible, keeping mutexes private within classes, and tightly bound to very specific class members.
cs: Programový kód vlákna izolujte co nejvíce to jde, mutexy udržujte v rámci tříd privátní a pevně je spojte s velmi konkrétně zaměřenými členy třídy.

note: (itstool) path: item/p
en: All mutexes should be clearly commented beside their declaration, indicating which other structures or variables they protect access to. Similarly, those variables should be commented saying that they should <em>only</em> be accessed with that mutex held.
cs: U všech deklarací mutexů by měly být srozumitelné komentáře, ve kterých jsou uvedeny struktury nebo proměnné, k nimž chrání přístup. A obdobně by u oněch proměnných měl být komentář říkající, že by se k nim mělo přistupovat <em>pouze</em> pomocí mutexu, který je drží.

note: (itstool) path: item/p
en: Be careful about interactions between main contexts and threads. For example, <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add-seconds"><code>g_timeout_add_seconds()</code></link> adds a timeout <em>to be executed in the global default main context</em>, which is being run in the main thread, <em>not necessarily</em> the current thread. Getting this wrong can mean that work intended for a worker thread accidentally ends up being executed in the main thread anyway. (See also: <link xref="main-contexts#default-contexts"/>.)
cs: Buďte opatrní s interakcemi mezi hlavním kontextem a vlákny. Například funkce <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add-seconds"><code>g_timeout_add_seconds()</code></link> přidává časovač, <em>který bude spuštěn v globálním výchozím hlavním kontextu</em>, který běží v hlavním vlákně, což <em>není nutně</em> aktuální vlákno. Když se to udělá špatně, může to znamenat, že to co bylo zamýšleno pro pracovní vlákno nešťastnou náhodou skončí spuštěné mimo v hlavním vlákně. (Viz také: <link xref="main-contexts#default-contexts"/>.)

note: (itstool) path: section/title
en: Debugging
cs: Ladění

note: (itstool) path: section/p
en: Debugging threading issues is tricky, both because they are hard to reproduce, and because they are hard to reason about. This is one of the big reasons for avoiding using threads in the first place.
cs: Ladění vláken je poněkud zapeklité. Jednak protože se chyby těžko reprodukují a jednak protože je těžké odhalit jejich původ. To je jeden z hlavních důvodů, proč se vyhýbat vláknům a nevolit je jako první řešení.

note: (itstool) path: section/p
en: However, if a threading issue does arise, <link xref="tooling#helgrind-and-drd">Valgrind’s drd and helgrind tools are useful</link>.
cs: Při výskytu takovéto chyby však mohou být <link xref="tooling#helgrind-and-drd">užitečné nástroje drd a helgrind z Valgrind</link>.

note: (itstool) path: info/desc
en: Using the right tool for various tasks
cs: Použití správných nástrojů pro různé úkoly

note: (itstool) path: page/title
en: Tooling
cs: Nástroje

note: (itstool) path: page/p
en: Development tools are much more than just a text editor and a compiler. Correct use of the right tools can drastically ease debugging and tracking down of complex problems with memory allocation and system calls, amongst other things. Some of the most commonly used tools are described below; other tools exist for more specialized use cases, and should be used when appropriate.
cs: Vývojářskými nástroji nejsou jen textový editor a kompilátor. Správné použití správných nástrojů může, mimo jiné, významně usnadnit ladění a sledování složitých problémů s přidělováním paměti a systémovým voláním. Některé z nejběžněji používaných nástrojů jsou popsány dále. Ostatní existující nástroje jsou povětšinou pro specializovanější situace a měly by být použity, když je to vhodné.

note: (itstool) path: page/p
en: An overarching principle to use when developing is to always have as many debugging options enabled as possible, rather than keeping them disabled until near release time. By constantly testing code with all available debug tooling, bugs can be caught early on, before they become ingrained in code and thus harder to remove.
cs: Obecný princip, který platí při vývoji, je mít vždy povoleno tolik ladicích voleb, kolik je jen možné, a ne je mít vypnuté až do doby těsně před vydáním. Tím že se kód neustále testuje všemi dostupnými ladicími nástroji, zachytíte chyby již v zárodku, dřív než se zakoření hluboko do kódu a bude těžší je odstranit.

note: (itstool) path: page/p
en: Practically, this means having all compiler and other tool warnings enabled and set to fail the build process with an error if they are emitted.
cs: Prakticky to znamená, mít zapnutá varování u kompilátoru a všech dalších nástrojů a zapnout selhání procesu sestavení s chybou při jejich výskytu.

note: (itstool) path: item/p
en: Compile frequently with a second compiler. (<link xref="#gcc-and-clang"/>)
cs: Kompilujte často pomocí druhého kompilátoru. (<link xref="#gcc-and-clang"/>)

note: (itstool) path: item/p
en: Enable a large selection of compiler warnings and make them fatal. (<link xref="#gcc-and-clang"/>)
cs: Povolte co největší počet varování kompilátoru a nastavte je jako kritická. (<link xref="#gcc-and-clang"/>)

note: (itstool) path: item/p
en: Use GDB to debug and step through code. (<link xref="#gdb"/>)
cs: Používejte GDB k ladění a krokování kódu. (<link xref="#gdb"/>)

note: (itstool) path: item/p
en: Use Valgrind to analyze memory usage, memory errors, cache and CPU performance and threading errors. (<link xref="#valgrind"/>)
cs: Používejte Valgrind k analýze využití paměti, paměťových chyb, výkonu mezipaměti a procesoru a chyb s vlákny. (<link xref="#valgrind"/>)

note: (itstool) path: item/p
en: Use gcov and lcov to analyze unit test coverage. (<link xref="#gcov-and-lcov"/>)
cs: Používejte gcov a lcov k pokrytí analytickými jednotkovými testy. (<link xref="#gcov-and-lcov"/>)

note: (itstool) path: item/p
en: Use compiler sanitizers to analyze memory, thread and undefined behavior problems. (<link xref="#sanitizers"/>)
cs: Používejte sanitizéry k analýze problémů s pamětí, vlákny a nedefinovaným chováním. (<link xref="#sanitizers"/>)

note: (itstool) path: item/p
en: Submit to Coverity as a cronjob and eliminate static analysis errors as they appear. (<link xref="#coverity"/>)
cs: Kontrolu pomocí Coverity provádějte jako pravidelnou úlohu a chyby statické analýzy odstraňte hned, jak se objeví. (<link xref="#coverity"/>)

note: (itstool) path: item/p
en: Use Clang static analyzer and Tartan regularly to eliminate statically analysable errors locally. (<link xref="#clang-static-analyzer"/>)
cs: Používejte pravidelně statický analyzátor Clang a Tartan k odstranění místních chyb, které lze analyzovat staticky. (<link xref="#clang-static-analyzer"/>)

note: (itstool) path: section/title
en: GCC and Clang
cs: GCC a Clang

note: (itstool) path: section/p
en: <link href="https://gcc.gnu.org/onlinedocs/gcc/">GCC</link> is the standard C compiler for Linux. An alternative exists in the form of <link href="http://clang.llvm.org/docs/UsersManual.html">Clang</link>, with comparable functionality. Choose one (probably GCC) to use as a main compiler, but occasionally use the other to compile the code, as the two detect slightly different sets of errors and warnings in code. Clang also comes with a static analyzer tool which can be used to detect errors in code without compiling or running it; see <link xref="#clang-static-analyzer"/>.
cs: <link href="https://gcc.gnu.org/onlinedocs/gcc/">GCC</link> je standardní kompilátor pro Linux. Existuje i alternativa v podobě kompilátoru <link href="http://clang.llvm.org/docs/UsersManual.html">Clang</link> s obdobnou funkcionalitou. Jeden z nich (nejspíše GCC) si zvolte jako hlavní, ale příležitostně provádějte kompilaci kódu i druhým, abyste objevili trochu jinou skupinu chyb a varování v kódu. Clang dáva k dispozici také nástroj pro statickou analýzu, který můžete použít k odhalení chyb v kódu bez jeho kompilace nebo spuštění. Viz <link xref="#clang-static-analyzer"/>.

note: (itstool) path: section/p
en: Both compilers should be used with as many warning flags enabled as possible. Although compiler warnings do occasionally provide false positives, most warnings legitimately point to problems in the code, and hence should be fixed rather than ignored. A development policy of enabling all warning flags and also specifying the <code>-Werror</code> flag (which makes all warnings fatal to compilation) promotes fixing warnings as soon as they are introduced. This helps code quality. The alternative of ignoring warnings leads to long debugging sessions to track down bugs caused by issues which would have been flagged up by the warnings. Similarly, ignoring warnings until the end of the development cycle, then spending a block of time enabling and fixing them all wastes time.
cs: Oba dva kompilátory by se měly používat s co nejvíce zapnutými přepínači varování je možné. Přestože kompilátor může příležitostně poskytnout falešné varování, většina varování oprávněně ukazuje na problém v programovém kódu a proto by měla být opravena, a ne ignorována. Zásadou pro vývojáře je zapnout co nejvíce přepínačů varování a rovněž zadat <code>-Werror</code> (ten způsobí, že všechna varování způsobí selhání kompilace), aby byli přinuceni opravit varování hned, jak se objeví. To pomáhá zvyšovat kvalitu kódu. Naopak ignorování varování vede ve výsledků ke zdlouhavému ladění kvůli vyhledání chyby, která je způsobená problémem, který byl již dříve označen varováním. Stejně tak, když budete ignorovat varování až do konce vývojového cyklu, strávíte násobně více času jejich opravami na závěr.

note: (itstool) path: section/p
en: Both GCC and Clang support a wide range of compiler flags, only some of which are related to modern, multi-purpose code (for example, others are outdated or architecture-specific). Finding a reasonable set of flags to enable can be tricky, and hence the <link href="http://www.gnu.org/software/autoconf-archive/ax_compiler_flags.html"> <code>AX_COMPILER_FLAGS</code></link> macro exists.
cs: Jak GCC, tak Clang, podporují velké množství přepínačů, ale jen některé z nich se vztahují k modernímu víceúčelovému kódu (ostatní jsou například zastaralé nebo závislé na architektuře). Najít vhodnou sadu přepínačů, které je třeba zapnout, může být trochu magie, a proto existuje makro <link href="http://www.gnu.org/software/autoconf-archive/ax_compiler_flags.html"> <code>AX_COMPILER_FLAGS</code></link>.

note: (itstool) path: section/p
en: <code>AX_COMPILER_FLAGS</code> enables a consistent set of compiler warnings, and also tests that the compiler supports each flag before enabling it. This accounts for differences in the set of flags supported by GCC and Clang. To use it, add <code>AX_COMPILER_FLAGS</code> to <file>configure.ac</file>. If you are using in-tree copies of autoconf-archive macros, copy <link href="http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_compiler_flags.m4"> <file>ax_compiler_flags.m4</file></link> to the <file>m4/</file> directory of your project. Note that it depends on the following autoconf-archive macros which are GPL-licensed so potentially cannot be copied in-tree. They may have to remain in autoconf-archive, with that as a build time dependency of the project:
cs: <code>AX_COMPILER_FLAGS</code> zapíná jednotnou sadu varování kompilátoru a také, před tím než je zapne, jednotlivě testuje, jestli je kompilátor podporuje. Vyrovnává se tím s rozdíly mezi překladači GCC a Clang v sadě podporovaných přepínačů. Pro použití stačí přidat <code>AX_COMPILER_FLAGS</code> do <file>configure.ac</file>. Pokud používáte kopii maker autoconf-archive ve stromu se zdrojovými kódy, zkopírujte <link href="http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_compiler_flags.m4"><file>ax_compiler_flags.m4</file></link> do složky <file>m4</file> ve svém projektu. Mějte na paměti, že závisí na následujících makrech z autoconf-archive, která jsou pod licenci GPL, takže existuje možnost, že z licenčních důvodů je nebudete moci nakopírovat. Pak je budete muset ponechat v autoconf-archive, který pak bude závislostí pro sestavovací proces projektu:

note: (itstool) path: section/p
en: <code>AX_COMPILER_FLAGS</code> supports disabling <code>-Werror</code> for release builds, so that releases may always be built against newer compilers which have introduced more warnings. Set its third parameter to ‘yes’ for release builds (and only release builds) to enable this functionality. Development and CI builds should always have <code>-Werror</code> enabled.
cs: <code>AX_COMPILER_FLAGS</code> podporuje vypnutí <code>-Werror</code> u sestavení pro vydání, takže tato vydání mohou být vždy sestavena oproti novějšímu kompilátoru, který může mít zavedeno více varování. Pro zapnutí této funkce nastavte u sestavení pro vydání (a jen u nich) jeho třetí parametr na „yes“. Vývojová sestavení a sestavení průběžné integrace by měla mít přepínač <code>-Werror</code> vždy zapnutý.

note: (itstool) path: section/p
en: Release builds can be detected using the <link href="http://www.gnu.org/software/autoconf-archive/ax_is_release.html"><code>AX_IS_RELEASE</code></link> macro, the result of which can be passed directly to <code>AX_COMPILER_FLAGS</code>:
cs: Sestavení pro vydání lze detekovat pomocí makra <link href="http://www.gnu.org/software/autoconf-archive/ax_is_release.html"><code>AX_IS_RELEASE</code></link>, jehož výsledek můžete předat přímo do <code>AX_COMPILER_FLAGS</code>:

note: (itstool) path: section/p
en: The choice of release stability policy (the first argument to <code>AX_IS_RELEASE</code>) should be made per project, taking the project’s <link xref="versioning">versioning stability</link> into account.
cs: Volba zásad pro stabilitu vydání (první argument pro <code>AX_IS_RELEASE</code>) by měla být prováděna pro každý projekt zvlášť, přičemž je třeba brát do úvahy <link xref="versioning">číslování verzí podle stability</link>.

note: (itstool) path: section/p
en: GDB is the standard debugger for C on Linux. Its most common uses are for debugging crashes, and for stepping through code as it executes. A full tutorial for using GDB is given <link href="https://sourceware.org/gdb/current/onlinedocs/gdb/"> here</link>.
cs: GDB je standardní ladicí program pro C v Linuxu. Je nejběžněji používán k ladění pádů a ke krokování spuštěného kódu. Ucelený průvodce použitím GDB je poskytnut <link href="https://sourceware.org/gdb/current/onlinedocs/gdb/">zde</link>.

note: (itstool) path: section/p
en: To run GDB on a program from within the source tree, use: <cmd>libtool exec gdb --args <var>./program-name</var> <var>--some --arguments --here</var></cmd>
cs: Ke spuštění GDB vůči programu uvnitř stromu jeho zdrojových kódů použijte: <cmd>libtool exec gdb --args <var>./nazev-programu</var> <var>--nejake --jeho --argumenty</var></cmd>

note: (itstool) path: section/p
en: This is necessary due to libtool wrapping each compiled binary in the source tree in a shell script which sets up some libtool variables. It is not necessary for debugging installed executables.
cs: Takto je to nutné z důvodu, aby libtool obalila ve stromu zdrojových kódů každý zkompilovaný binární soubor do shellového skriptu, který nastaví některé proměnné pro libtool. Není to zapotřebí pro ladění nainstalovaných spustitelných souborů.

note: (itstool) path: section/p
en: GDB has many advanced features which can be combined to essentially create small debugging scripts, triggered by different breakpoints in code. Sometimes this is a useful approach (for example, for <link href="https://tecnocode.co.uk/2010/07/12/reference-count-debugging-with-gdb/"> reference count debugging</link>), but sometimes simply using <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-debug"> <code>g_debug()</code></link> to output a debug message is simpler.
cs: GDB má spoustu pokročilých funkcí, které lze kombinovat, abyste v podstatě vytvořili malé ladicí skripty, které se spouští v různých bodech přerušení v kódu. Někdy se to opravdu hodí (například pro <link href="https://tecnocode.co.uk/2010/07/12/reference-count-debugging-with-gdb/">ladění počítání odkazů</link>), ale jindy je jednodušší použít prostě samotné <link href="https://developer.gnome.org/glib/stable/glib-Message-Logging.html#g-debug"> <code>g_debug()</code></link> pro výpis ladicích zpráv.

note: (itstool) path: section/p
en: Valgrind is a suite of tools for instrumenting and profiling programs. Its most famous tool is <link xref="#memcheck">memcheck</link>, but it has several other powerful and useful tools too. They are covered separately in the sections below.
cs: Valgrind je sada nástrojů pro měření a profilování programů. Jeho nejznámějším nástrojem je <link xref="#memcheck">memcheck</link>, ale má i několik dalších mocných a užitečných nástrojů. Jednotlivě se jim věnují následující oddíly.

note: (itstool) path: section/p
en: A useful way of running Valgrind is to run a program’s unit test suite under Valgrind, setting Valgrind to return a status code indicating the number of errors it encountered. When run as part of <cmd>make check</cmd>, this will cause the checks to succeed if Valgrind finds no problems, and fail otherwise. However, running <cmd>make check</cmd> under Valgrind is not trivial to do on the command line. A macro, <link href="http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html"> <code>AX_VALGRIND_CHECK</code></link> can be used which adds a new <cmd>make check-valgrind</cmd> target to automate this. To use it:
cs: Vhodným způsobem, jak spustit Valgrind, je spustit pod ním sadu jednotkových testů programu a nastavit jej, aby vrátil stavový kód sdělující množství napočítaných chyb. Když běží jako součást <cmd>make check</cmd>, způsobí to, že je kontrola úspěšná, když Valgrind nenajde žádný problém a selže v opačném případě. Avšak spuštění <cmd>make check</cmd> pod Valgrind není jednoduché provést v příkazové řádce. Můžete použít makro <link href="http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html"><code>AX_VALGRIND_CHECK</code></link>, které přidá nový cíl <cmd>make check-valgrind</cmd> pro zautomatizování. Použijte jej následovně:

note: (itstool) path: item/p
en: Copy <link href="http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_valgrind_check.m4"> <file>ax_valgrind_check.m4</file></link> to the <file>m4/</file> directory of your project.
cs: Zkopírujte <link href="http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_valgrind_check.m4"> <file>ax_valgrind_check.m4</file></link> do složky <file>m4/</file> ve svém projektu.

note: (itstool) path: item/p
en: Add <code>AX_VALGRIND_CHECK</code> to <file>configure.ac</file>.
cs: Přidejte <code>AX_VALGRIND_CHECK</code> do <file>configure.ac</file>.

note: (itstool) path: item/p
en: Add <code>@VALGRIND_CHECK_RULES@</code> to the <file>Makefile.am</file> in each directory which contains unit tests.
cs: Přidejte <code>@VALGRIND_CHECK_RULES@</code> do <file>Makefile.am</file> v každé složce, která obsahuje jednotkové testy.

note: (itstool) path: section/p
en: When <cmd>make check-valgrind</cmd> is run, it will save its results in <file>test-suite-*.log</file>, one log file per tool. Note that you will need to run it from the directory containing the unit tests.
cs: Když je spuštěno <cmd>make check-valgrind</cmd>, uloží se jeho výsledky do <file>test-suite-*.log</file>, jeden soubor se záznamem pro každý z nástrojů. Nezapomeňte, že jej musíte spustit ve složce, která obsahuje jednotkové testy.

note: (itstool) path: section/p
en: Valgrind has a way to suppress false positives, by using <link href="http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress"> suppression files</link>. These list patterns which may match error stack traces. If a stack trace from an error matches part of a suppression entry, it is not reported. For various reasons, GLib currently causes a number of false positives in <link xref="#memcheck">memcheck</link> and <link xref="#helgrind-and-drd">helgrind and drd</link> which must be suppressed by default for Valgrind to be useful. For this reason, every project should use a standard GLib suppression file as well as a project specific one.
cs: Valgrind má způsob, jak potlačit falešná hlášení pomocí <link href="http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress">potlačovacích souborů</link>. V nich jsou uvedeny vzory, které mohou odpovídat výpisům chyb zásobníku. Pokud výpis zásobníku pro nějakou chybu odpovídá části potlačovacího záznamu, není nahlášen. Z jistých důvodů GLib v současnosti způsobuje řadu falešných hlášení v nástrojích <link xref="#memcheck">memcheck</link> a <link xref="#helgrind-and-drd">helgrind a drd</link>, která je potřeba standardně potlačovat, aby byl Valgrind vůbec použitelný. Proto by měl každý projekt mimo svého vlastního potlačovacího souboru používat i standardní potlačovací soubor pro GLib.

note: (itstool) path: section/p
en: Suppression files are supported by the <code>AX_VALGRIND_CHECK</code> macro:
cs: Potlačovací soubory jsou podporovány pomocí makra <code>AX_VALGRIND_CHECK</code>:

note: (itstool) path: section/p
en: memcheck is a memory usage and allocation analyzer. It detects problems with memory accesses and modifications of the heap (allocations and frees). It is a highly robust and mature tool, and its output can be entirely trusted. If it says there is ‘definitely’ a memory leak, there is definitely a memory leak which should be fixed. If it says there is ‘potentially’ a memory leak, there may be a leak to be fixed, or it may be memory allocated at initialization time and used throughout the life of the program without needing to be freed.
cs: memcheck je analyzátor využití a přidělování paměti. Zjišťuje problémy s přístupem k paměti a změnami v haldě (přidělování a uvolňování). Jedná se o robustní a zaběhnutý nástroj a jeho výstupům se dá vcelku důvěřovat. Když oznámí, že se „určitě“ jedná o únik paměti, tak se určitě jedná o únik paměti, který byste měli opravit. Když řekne, že se jedná o „potenciální“ únik paměti, možná jde o únik, který byste měli opravit, nebo může jít o přidělení paměti při počáteční inicializaci, které je pak používána po celou dobu běhu programu a není potřeba ji uvolňovat.

note: (itstool) path: section/p
en: To run memcheck manually on an installed program, use:
cs: K ručnímu spuštění memcheck vůči nainstalovanému programu použijte:

note: (itstool) path: section/p
en: <cmd>valgrind --tool=memcheck --leak-check=full <var>my-program-name</var></cmd>
cs: <cmd>valgrind --tool=memcheck --leak-check=full <var>název-vašeho-programu</var></cmd>

note: (itstool) path: section/p
en: Or, if running your program from the source directory, use the following to avoid running leak checking on the libtool helper scripts:
cs: Nebo, když spouštíte svůj program ze složky se zdrojovými kódy, použijte následující, abyste se vyhnuli kontrole úniků v pomocných skriptech libtool:

note: (itstool) path: section/p
en: <cmd>libtool exec valgrind --tool=memcheck --leak-check=full <var>./my-program-name</var></cmd>
cs: <cmd>libtool exec valgrind --tool=memcheck --leak-check=full <var>./název-vašeho-programu</var></cmd>

note: (itstool) path: section/p
en: Valgrind lists each memory problem it detects, along with a short backtrace (if you’ve compiled your program with debug symbols), allowing the cause of the memory error to be pinpointed and fixed.
cs: Valgrind vypíše všechny zjištěné problémy s pamětí, včetně krátkého výpisu zásobníku volání u každého z nich (za předpokladu, že jste program zkompilovali s ladicími symboly), díky čemuž lze paměťovou chybu dohledat a opravit.

note: (itstool) path: section/p
en: A full tutorial on using memcheck is <link href="http://valgrind.org/docs/manual/mc-manual.html">here</link>.
cs: Ucelený průvodce použitím nástroje memcheck je <link href="http://valgrind.org/docs/manual/mc-manual.html">zde</link>.

note: (itstool) path: section/title
en: cachegrind and KCacheGrind
cs: cachegrind a KCacheGrind

note: (itstool) path: section/p
en: cachegrind is a cache performance profiler which can also measure instruction execution, and hence is very useful for profiling general performance of a program. <link href="http://kcachegrind.sourceforge.net/html/Home.html"> KCacheGrind</link> is a useful UI for it which allows visualization and exploration of the profiling data, and the two tools should rarely be used separately.
cs: cachegrind je profilovací nástroj výkonu mezipaměti, který může měřit také provádění instrukcí a je tak velmi užitečný i pro profilování obecného výkonu programu. <link href="http://kcachegrind.sourceforge.net/html/Home.html"> KCacheGrind</link> je pak pro něj šikovné uživatelské rozhraní, které provádí grafické znázornění a můžete v něm zkoumat profilovací data. Tyto dva nástroje se tak obvykle používají dohromady.

note: (itstool) path: section/p
en: cachegrind works by simulating the processor’s memory hierarchy, so there are situations where it is <link href="http://valgrind.org/docs/manual/cg-manual.html#cg-manual.annopts.accuracy"> not perfectly accurate</link>. However, its results are always representative enough to be very useful in debugging performance hotspots.
cs: cachegrind funguje pomocí simulace hierarchie paměti procesoru, takže existují situace, kdy není <link href="http://valgrind.org/docs/manual/cg-manual.html#cg-manual.annopts.accuracy">zcela přesný</link>. Jeho výsledky jsou však vždy dostatečně reprezentativní, aby byly užitečné pro ladění výkonu v dotčených místech.

note: (itstool) path: section/p
en: A full tutorial on using cachegrind is <link href="http://valgrind.org/docs/manual/cg-manual.html">here</link>.
cs: Ucelený průvodce používáním nástroje cachegrind je <link href="http://valgrind.org/docs/manual/cg-manual.html">zde</link>.

note: (itstool) path: section/title
en: helgrind and drd
cs: helgrind a drd

note: (itstool) path: section/p
en: helgrind and drd are threading error detectors, checking for race conditions in memory accesses, and abuses of the <link href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html"> POSIX pthreads API</link>. They are similar tools, but are implemented using different techniques, so both should be used.
cs: helgrind a drd slouží ke zjišťování chyb týkajících se vláken, ke kontrole souběhových chyb v přístupu k paměti a chybného používání <link href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html">API vláken podle standardu POSIX</link>. Jedná se o dva podobné nástroje, ale používající ke své práci rozdílné techniky, takže by se měly používat oba.

note: (itstool) path: section/p
en: The kinds of errors detected by helgrind and drd are: data accessed from multiple threads without consistent locking, changes in lock acquisition order, freeing a mutex while it is locked, locking a locked mutex, unlocking an unlocked mutex, and several other errors. Each error, when detected, is printed to the console in a little report, with a separate report giving the allocation or spawning details of the mutexes or threads involved so that their definitions can be found.
cs: Druhy chyb detekované nástroji helgrind a drd jsou: přístup k datům z více vláken bez jednotného zamykání, změny v pořadí získávání zámků, uvolňování zamknutého mutexu, zamykání zamknutého mutexu, odemykání odemčeného mutexu a několik dalších chyb. Každá chyba, která je objevena, je vypsána do konzole v podobě drobné výstupní sestavy s oddělenu částí poskytující podrobnosti o alokaci nebo vzniku mutexů nebo vláken, se kterými to souvisí, takže pak můžete snadno najít jejich definici.

note: (itstool) path: section/p
en: helgrind and drd can produce more false positives than memcheck or cachegrind, so their output should be studied a little more carefully. However, threading problems are notoriously elusive even to experienced programmers, so helgrind and drd errors should not be dismissed lightly.
cs: helgrind a drd produkují více falešných hlášení, než memcheck a cachegrind, takže jejich výstupy je třeba prostudovat trochu obezřetněji. Problémy s vlákny jsou ale notoricky těžko polapitelné i pro zkušené programátory, takže tyto nástroje by neměly být jen tak zavrhnuty.

note: (itstool) path: section/p
en: Full tutorials on using helgrind and drd are <link href="http://valgrind.org/docs/manual/hg-manual.html">here</link> and <link href="http://valgrind.org/docs/manual/drd-manual.html"> here</link>.
cs: Ucelení průvodci používáním helgrind a drd jsou <link href="http://valgrind.org/docs/manual/hg-manual.html">zde</link> a <link href="http://valgrind.org/docs/manual/drd-manual.html">zde</link>.

note: (itstool) path: section/p
en: sgcheck is an array bounds checker, which detects accesses to arrays which have overstepped the length of the array. However, it is a very young tool, still marked as experimental, and hence may produce more false positives than other tools.
cs: sgcheck provádí kontrolu rozsahu polí. Umí odhalit přístup do pole, při kterém dojde k překročení délky pole. Jedná se ale o velmi raný nástroj, zatím označený jako experimentální, a proto může produkovat více falešných hlášení než jiné nástroje.

note: (itstool) path: section/p
en: As it is experimental, sgcheck must be run by passing <cmd>--tool=exp-sgcheck</cmd> to Valgrind, rather than <cmd>--tool=sgcheck</cmd>.
cs: Protože je experimentální, musí být spuštěn s předáním <cmd>--tool=exp-sgcheck</cmd> do Valgrindu, namísto <cmd>--tool=sgcheck</cmd>.

note: (itstool) path: section/p
en: A full tutorial on using sgcheck is <link href="http://valgrind.org/docs/manual/sg-manual.html">here</link>.
cs: Ucelený průvodce použitím sgcheck je <link href="http://valgrind.org/docs/manual/sg-manual.html">zde</link>.

note: (itstool) path: section/title
en: gcov and lcov
cs: gcov a lcov

note: (itstool) path: section/p
en: <link href="https://gcc.gnu.org/onlinedocs/gcc/Gcov.html">gcov</link> is a profiling tool built into GCC, which instruments code by adding extra instructions at compile time. When the program is run, this code generates <file>.gcda</file> and <file>.gcno</file> profiling output files. These files can be analyzed by the <cmd>lcov</cmd> tool, which generates visual reports of code coverage at runtime, highlighting lines of code in the project which are run more than others.
cs: <link href="https://gcc.gnu.org/onlinedocs/gcc/Gcov.html">gcov</link> je profilovací nástroj vestavěný v GCC, který během kompilace obohatí programový kód přidáním doplňujících instrukcí. Když je pak program spuštěn, generuje výstupní profilovací soubory <file>.gcda</file> a <file>.gcno</file>. Tyto soubory lze analyzovat pomocí nástroje <cmd>lcov</cmd>, který generuje přehlednou výstupní sestavu pokrytí kódu za běhu, v níž zvýrazní řádky kódu, které běží déle než ostatní.

note: (itstool) path: section/p
en: A critical use for this code coverage data collection is when running the unit tests: if the amount of code covered (for example, which particular lines were run) by the unit tests is known, it can be used to guide further expansion of the unit tests. By regularly checking the code coverage attained by the unit tests, and expanding them towards 100%, you can be sure that the entire project is being tested. Often it is the case that a unit test exercises most of the code, but not a particular control flow path, which then harbours residual bugs.
cs: Kritické využití pro nasbíraná data o pokrytí kódu je při běhu jednotkových testů: když je množství kódu pokrytého jednotkovými testy (např. které konkrétní řádky proběhly) známé, může být použito jako vodítko pro další rozšiřování jednotkových testů. Pravidelnou kontrolou pokrytí kódu získaného jednotkovými testy a jeho dalším rozšířením na 100 % můžete zajistit, že bude testován celý projekt. Častým případem je, že jednotkové testy zkouší většinu kódu, ale ne konkrétně cestu řízeného průchodu, ve které se pak ukrývá zbytek chyb.

note: (itstool) path: section/p
en: lcov supports <link href="https://en.wikipedia.org/wiki/Code_coverage#Basic_coverage_criteria"> branch coverage measurement</link>, so is not suitable for demonstrating coverage of safety critical code. It is perfectly suitable for non-safety critical code.
cs: lconv podporuje <link href="https://en.wikipedia.org/wiki/Code_coverage#Basic_coverage_criteria">měření pokrytí větve</link>, takže není vhodný jako ukázkové pokrytí kritického kódu z hlediska bezpečnosti. Je naopak perfektně vhodný pro kód, který není z hlediska bezpečnosti kritický.

note: (itstool) path: section/p
en: As code coverage has to be enabled at both compile time and run time, a macro is provided to make things simpler. The <link href="http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html"> <code>AX_CODE_COVERAGE</code></link> macro adds a <cmd>make check-code-coverage</cmd> target to the build system, which runs the unit tests with code coverage enabled, and generates a report using <cmd>lcov</cmd>.
cs: Protože pokrytí kódu musí být povoleno jak při kompilaci, tak za běhu, je pro zjednodušení poskytováno makro. Makro <link href="http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html"> <code>AX_CODE_COVERAGE</code></link> přidává do sestavovacího systému cíl <cmd>make check-code-coverage</cmd>, který spustí jednotkové testy s povoleným pokrytím kódu a vygeneruje výstupní sestavu pomocí <cmd>lcov</cmd>.

note: (itstool) path: section/p
en: To add <code>AX_CODE_COVERAGE</code> support to a project:
cs: Když chcete do svého projektu přidat podporu pro <code>AX_CODE_COVERAGE</code>:

note: (itstool) path: item/p
en: Copy <link href="http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_code_coverage.m4"> <file>ax_code_coverage.m4</file></link> to the <file>m4/</file> directory of your project.
cs: Zkopírujte <link href="http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_code_coverage.m4"><file>ax_code_coverage.m4</file></link> do složky <file>m4/</file> svého projektu.

note: (itstool) path: item/p
en: Add <code>AX_CODE_COVERAGE</code> to <file>configure.ac</file>.
cs: Přidejte <code>AX_CODE_COVERAGE</code> do <file>configure.ac</file>.

note: (itstool) path: item/p
en: Add <code>@CODE_COVERAGE_RULES</code> to the top-level <file>Makefile.am</file>.
cs: Přidejte <code>@CODE_COVERAGE_RULES</code> do <file>Makefile.am</file> v nejvyšší úrovni.

note: (itstool) path: item/p
en: Add <code>$(CODE_COVERAGE_CFLAGS)</code> to the automake <code><var>*</var>_CFLAGS</code> variable for each target you want coverage for, for example for all libraries but no unit test code. Do the same for <code>$(CODE_COVERAGE_LDFLAGS)</code> and <code><var>*</var>_LDFLAGS</code>.
cs: AdPřidejte <code>$(CODE_COVERAGE_CFLAGS)</code> do proměnné <code><var>*</var>_CFLAGS</code> systému automake pro každý cíl, který chcete pokrýt, například pro všechny knihovny, ale už ne tak pro jednotkové testy. To stejné proveďte pro <code>$(CODE_COVERAGE_LDFLAGS)</code> a <code><var>*</var>_LDFLAGS</code>.

note: (itstool) path: section/p
en: Documentation on using gcov and lcov is <link href="http://ltp.sourceforge.net/coverage/lcov.php">here</link>.
cs: Dokumentace k používání gcov a lcov je <link href="http://ltp.sourceforge.net/coverage/lcov.php">zde</link>.

note: (itstool) path: section/title
en: Address, Thread and Undefined Behavior Sanitizers
cs: Sanitizéry adres, vláken a nedefinovaného chování

note: (itstool) path: section/p
en: GCC and Clang both support several sanitizers: sets of extra code and checks which can be optionally compiled in to an application and used to flag various incorrect behaviors at runtime. They are powerful tools, but have to be enabled specially, recompiling your application to enable and disable them. They cannot be enabled at the same time as each other, or used at the same time as <link xref="#valgrind">Valgrind</link>. They are still young, so have little integration with other tooling.
cs: Jak GCC, tak Clang, mají podporu několika sanitizérů: sadu dodatečného kódu a kontrol, které mohou být volitelně zakompilovány do vaší aplikace a použity k označené různorodého nesprávného chování za běhu. Jedná se o mocné nástroje, ale musí být zapnuty či vypnuty tak, že překompilujete svoji aplikaci. Nemohou být zapnuty zárovneň s jinými a nemohou být použity naráz s nástroji <link xref="#valgrind">Valgrind</link>. Jedná se stále o poměrně novou funkcionalitu, takže je jen málo integrována s jinými nástroji.

note: (itstool) path: section/p
en: All sanitizers are available for both GCC and Clang, accepting the same set of compiler options.
cs: Všechny sanitizéry jsou dostupné pro překladač GCC i Clang a přijímají stejnou sadu přepínačů kompilátoru.

note: (itstool) path: section/title
en: Address Sanitizer
cs: Sanitizér adres

note: (itstool) path: section/p
en: The <link href="https://code.google.com/p/address-sanitizer/">address sanitizer</link> (‘asan’) detects use-after-free and buffer overflow bugs in C and C++ programs. A full tutorial on using asan is <link href="http://clang.llvm.org/docs/AddressSanitizer.html#usage">available for Clang</link> — the same instructions should work for GCC.
cs: <link href="https://code.google.com/p/address-sanitizer/">Sanitizér adres</link> („asan“) detekuje chyby „použití po uvolnění“ a přetečení vyrovnávací paměti v programech C a C++. Vyčerpávající výklad k používání asan je <link href="http://clang.llvm.org/docs/AddressSanitizer.html#usage">k dispozici pro Clang</link>, ale stejné postupy platí i pro GCC.

note: (itstool) path: section/title
en: Thread Sanitizer
cs: Sanitizér vláken

note: (itstool) path: section/p
en: The <link href="https://code.google.com/p/thread-sanitizer/">thread sanitizer</link> (‘tsan’) detects data races on memory locations, plus a variety of invalid uses of POSIX threading APIs. A full tutorial on using tsan is <link href="http://clang.llvm.org/docs/ThreadSanitizer.html#usage">available for Clang</link> — the same instructions should work for GCC.
cs: <link href="https://code.google.com/p/thread-sanitizer/">Sanitizér vláken</link> („tsan“ – thread sanitizer) zjišťuje souběhy v přístupu k datům v paměťových místech a k tomu také různá nesprávná použití API pro práci s vlákny podle standardu POSIX. Celistvý průvodce používáním nástroje tsan je <link href="http://clang.llvm.org/docs/ThreadSanitizer.html#usage">k dispozici pro Clang</link>, ale stejné postupy by měly platit i pro GCC.

note: (itstool) path: section/title
en: Undefined Behavior Sanitizer
cs: Sanitizér nedefinovaného chování

note: (itstool) path: section/p
en: The undefined behavior sanitizer (‘ubsan’) is a collection of smaller instrumentations which detect various potentially undefined behaviors in C programs. A set of instructions for enabling ubsan is <link href="http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation">available for Clang</link> — the same instructions should work for GCC.
cs: Sanitizér nedefinovaného chování („ubsan“ – undefined behavior sanitizer) je sbírka drobných nástrojů, které zjišťují různá potencionálně nedefinovaná chování v programech napsaných v jazyce C. Sada pokynů pro zapnutí ubsanu je <link href="http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation">k dispozici pro Clang</link>, ale stejně by to mělo fungovat i pro GCC.

note: (itstool) path: section/p
en: <link href="http://scan.coverity.com/">Coverity</link> is one of the most popular and biggest commercial static analyzer tools available. However, it is available to use free for Open Source projects, and any project is encouraged to <link href="https://scan.coverity.com/users/sign_up">sign up</link>. <link href="https://scan.coverity.com/faq#how-get-project-included-in-scan"> Analysis is performed</link> by running some analysis tools locally, then uploading the source code and results as a tarball to Coverity’s site. The results are then visible online to members of the project, as annotations on the project’s source code (similarly to how lcov presents its results).
cs: <link href="http://scan.coverity.com/">Coverity</link> je jeden z nejpopulárenějších a největší komerční dostupný nástroj pro statickou analýzu. Přestože je komerční, je volně k dispozici pro projekty Open Source, akorát je projekt vyzván k <link href="https://scan.coverity.com/users/sign_up">přihlášení</link>. <link href="https://scan.coverity.com/faq#how-get-project-included-in-scan">Analýza je prováděna</link> spuštěním některých analytických nástrojů lokálně a následně jsou zdrojový kód i výsledky v zabalené podobě nahrány na servery Coverity. Výsledky jsou pak členům projektu viditelné on-line v podobě poznámek u zdrojového kódu (obdobně, jako své výsledky podává lcov).

note: (itstool) path: section/p
en: As Coverity cannot be run entirely locally, it cannot be integrated properly into the build system. However, scripts do exist to automatically scan a project and upload the tarball to Coverity regularly. The recommended approach is to run these scripts regularly on a server (typically as a cronjob), using a clean checkout of the project’s git repository. Coverity automatically e-mails project members about new static analysis problems it finds, so the same approach as for <link xref="#gcc-and-clang">compiler warnings</link> can be taken: eliminate all the static analysis warnings, then eliminate new ones as they are detected.
cs: Protože Coverity nelze jako celek spustit lokálně, nelze jej ani pořádně zaintegrovat do systému sestavení. Existují ale skripty, které projekt automaticky pravidelně proskenují a zabalená data nahrají na servery Coverity. Doporučovaný přístup je spouštět tyto skripty pravidelně na serveru (typicky jako cronjob) a předtím stáhnout čisté zdrojové kódy z repozitáře git projektu. Coverity zašle členům projektu e-mail s nově nalezenými problémy ve statické analýze, takže může být zvolen stejný přístup, jako k <link xref="#gcc-and-clang">varováním kompilátoru</link>: řešte všechna varování statické analýzy a řešte je hned, jak jsou nalezena.

note: (itstool) path: section/p
en: Coverity is good, but it is not perfect, and it does produce a number of false positives. These should be marked as ignored in the online interface.
cs: Coverity je dobrý, ale ne dokonalý nástroj a produkuje řadu falešných hlášení. Ta lze ale v rozhraní příkazového řádku označit, aby byla ignorována.

note: (itstool) path: section/title
en: Clang Static Analyzer
cs: Statický analyzátor Clang

note: (itstool) path: section/p
en: One tool which can be used to perform static analysis locally is the <link href="http://clang-analyzer.llvm.org/">Clang static analyzer</link>, which is a tool co-developed with the <link xref="#gcc-and-clang">Clang compiler</link>. It detects a variety of problems in C code which compilers cannot, and which would otherwise only be detectable at run time (using unit tests).
cs: Jedním z nástrojů, které můžete používat k provádění místní statické analýzy, je <link href="http://clang-analyzer.llvm.org/">statický analyzátor Clang</link>, což je nástroj vyvíjený spolu s <link xref="#gcc-and-clang">kompilátorem Clang</link>. Detekuje různé problémy v kódu v jazyce C, které kompilátor rozpoznat nedokáže a které by tak byly zjištěny až za běhu (pomocí jednotkových testů).

note: (itstool) path: section/p
en: Clang produces some false positives, and there is no easy way to ignore them. The recommended thing to do is to <link href="http://clang-analyzer.llvm.org/faq.html#suppress_issue">file a bug report against the static analyzer</link>, so that the false positive can be fixed in future.
cs: Clang produkuje i pár falešných hlášení a není žádný jednoduchý způsob, jak je nechat ignorovat. Proto je při jejich výskytu doporučeno <link href="http://clang-analyzer.llvm.org/faq.html#suppress_issue">vyplnit pro statický analyzátor chybové hlášení</link>, aby mohla být do budoucna opravena.

note: (itstool) path: section/p
en: A full tutorial on using Clang is <link href="http://clang-analyzer.llvm.org/scan-build.html">here</link>.
cs: Ucelený průvodce používáním kompilátoru Clang je <link href="http://clang-analyzer.llvm.org/scan-build.html">zde</link>.

note: (itstool) path: section/p
en: However, for all the power of the Clang static analyzer, it cannot detect problems with specific libraries, such as GLib. This is a problem if a project uses GLib exclusively, and rarely uses POSIX APIs (which Clang does understand). There is a plugin available for the Clang static analyzer, called <link href="http://people.collabora.com/~pwith/tartan/">Tartan</link>, which extends Clang to support checks against some of the common GLib APIs.
cs: Přes veškeré vymoženosti, které statický analyzátor Clang poskytuje, nedokáže detekovat problémy se specifickými knihovnami, jako je GLib. Což je problém, když projekt používá výhradně GLib a jen zřídka API standardu POSIX (kterému Clang rozumí). Proto je k dispozici zásuvný modul pro statický analyzátor Clang, který se nazývá <link href="http://people.collabora.com/~pwith/tartan/">Tartan</link> a rozšiřuje Clang o podporu kontroly vůči některým běžným API knihovny GLib.

note: (itstool) path: section/p
en: Tartan is still young software, and will produce false positives and may crash when run on some code. However, it can find legitimate bugs quite quickly, and is worth running over a code base frequently to detect new errors in the use of GLib in the code. Please <link href="http://people.collabora.com/~pwith/tartan/#troubleshooting"> report any problems with Tartan</link>.
cs: Tartan je zatím velmi mladý software a může produkovat falešná hlášení a při spuštění vůči některému kód se může i zhroutit. Pomůže vám ale velmi rychle najít skutečné chyby a je vhodné jej vůči základnímu programovému kódu spouštět často, abyste odhalili nové chyby v použití GLib v svém kódu. Pokud s Tartanem narazíte na nějaké problémy, <link href="http://people.collabora.com/~pwith/tartan/#troubleshooting">nahlaste</link> je prosím.

note: (itstool) path: section/p
en: A full tutorial on enabling Tartan for use with the Clang static analyzer is <link href="http://people.collabora.com/~pwith/tartan/#usage-standalone"> here</link>. If set up correctly, the output from Tartan will be mixed together with the normal static analyzer output.
cs: Ucelený návod na zprovoznění Tartanu pro použití se statickým analyzátorem Clang najdete <link href="http://people.collabora.com/~pwith/tartan/#usage-standalone">zde</link>. Pokud je nastavení správné, je výstup z Tartanu dán dohromady s výstupem z normálního statického analyzátoru.

note: (itstool) path: info/desc
en: Designing software to be tested and writing unit tests for it
cs: Návrh softwaru tak, aby mohl být testován, a psaní jednotkových testů pro něj

note: (itstool) path: page/title
en: Unit Testing
cs: Jednotkové testy

note: (itstool) path: synopsis/p
en: Unit testing should be the primary method of testing the bulk of code written, because a unit test can be written once and run many times — manual tests have to be planned once and then manually run each time.
cs: Jednotkové testování by mělo být hlavním způsobem testování většiny napsaného kódu, protože jednotkové testy stačí napsat jednou, ale spouštět se mohou vícekrát  — ruční testy vymyslíte jednou, ale pak je musíte pokaždé ručně provést.

note: (itstool) path: synopsis/p
en: Development of unit tests starts with the architecture and API design of the code to be tested: code should be designed to be easily testable, or will potentially be very difficult to test.
cs: Vývoj jednotkových testů začíná návrhem architektury a API kódu, který má být testován: kód by měl být navržen tak, aby byl snadno testovatelný, protože jinak může být jeho testování velmi obtížné.

note: (itstool) path: item/p
en: Write unit tests to be as small as possible, but no smaller. (<link xref="#writing-unit-tests"/>)
cs: Pište jednotkové testy tak, aby byly co nejmenší možné, ale ne menší. (<link xref="#writing-unit-tests"/>)

note: (itstool) path: item/p
en: Use code coverage tools to write tests to get high code coverage. (<link xref="#writing-unit-tests"/>)
cs: Používejte k psaní testů nástroje pro pokrytí kódu, abyste kód pokryli co nejvíce. (<link xref="#writing-unit-tests"/>)

note: (itstool) path: item/p
en: Run all unit tests under Valgrind to check for leaks and other problems. (<link xref="#leak-checking"/>)
cs: Všechny jednotkové testy spouštějte pod Vlagrindem, aby se kontrolovaly úniky a jiné problémy. (<link xref="#leak-checking"/>)

note: (itstool) path: item/p
en: Use appropriate tools to automatically generate unit tests where possible. (<link xref="#test-generation"/>)
cs: Používejte příslušné nástroje pro automatické generování jednotkových testů všude, kde je to možné. (<link xref="#test-generation"/>)

note: (itstool) path: item/p
en: Design code to be testable from the beginning. (<link xref="#writing-testable-code"/>)
cs: Kód navrhujte už od začátku tak, aby byl testovatelný. (<link xref="#writing-testable-code"/>)

note: (itstool) path: section/title
en: Writing Unit Tests
cs: Psaní jednotkových testů

note: (itstool) path: section/p
en: Unit tests should be written in conjunction with looking at <link xref="tooling#gcov-and-lcov">code coverage information gained from running the tests</link>. This typically means writing an initial set of unit tests, running them to get coverage data, then reworking and expanding them to increase the code coverage levels. Coverage should be increased first by ensuring all functions are covered (at least in part), and then by ensuring all lines of code are covered. By covering functions first, API problems which will prevent effective testing can be found quickly. These typically manifest as internal functions which cannot easily be called from unit tests. Overall, coverage levels of over 90% should be aimed for; don’t just test cases covered by project requirements, test everything.
cs: Jednotkové testy by měly být psány v souladu s pohledem na <link xref="tooling#gcov-and-lcov">informace o pokrytí kódu získané z běžících testů</link>. To obvykle znamená napsaní nějaké počáteční sady jednotkových testů, jejich spuštění pro získání údajů o pokrytí, následné přepracování a jejich rozšíření, aby se zvýšila úroveň pokrytí. Pokrytí lze zvýšit za prvé snahou o pokrytí všech funkcí (nebo aspoň částečné pokrytí) a potom také snahou o pokrytí všech řádků kódu. Tím, že pokryjete nejdříve funkce, můžete rychle najít problémy v API, které se brání účinnému testování. Ty mají typicky podobu interních funkcí, které nelze jednoduše volat z jednotkových testů. Celkově se dá říci, že byste se měli zaměřit na úroveň pokrytí nad 90 %. Neomezujte testy jen na pokrytí věcí, které se vztahují k požadavkům na projekt – testujte vše.

note: (itstool) path: section/p
en: Like <link xref="version-control">git commits</link>, each unit test should be ‘as small as possible, but no smaller’, testing a single specific API or behavior. Each test case must be able to be run individually, without depending on state from other test cases. This is important to allow debugging of a single failing test, without having to step through all the other test code as well. It also means that a single test failure can easily be traced back to a specific API, rather than a generic ‘unit tests failed somewhere’ message.
cs: Obdobně jako <link xref="version-control">zařazení do gitu</link>, i jednotkový test by měl být „co nejmenší je možné, ale ne menší“ a testovat jen jedno konkrétní API nebo chování. Každý test musí být spustitelný samostatně, bez závislosti na stavu od ostatních testů. To je důležité, aby bylo možné ladit selhání jednotlivých testů samostatně, bez nutnosti procházet celou sérii dalších testů. Díky tomu lze také snadněji vysledovat selhání ke konkrétnímu API, namísto obecné hlášky „jednotkový test někde selhal“.

note: (itstool) path: section/p
en: GLib has support for unit testing with its <link href="https://developer.gnome.org/glib/stable/glib-Testing.html">GTest framework</link>, allowing tests to be arranged in groups and hierarchies. This means that groups of related tests can be run together for enhanced debugging too, by running the test binary with the <cmd>-p</cmd> argument: <cmd>./test-suite-name -p /path/to/test/group</cmd>.
cs: GLib má podporu pro jednotkové testování pomocí jejího <link href="https://developer.gnome.org/glib/stable/glib-Testing.html">frameworku GTest</link>, který umožňuje testy uspořádat do skupin a hierarchie. To znamená, že skupiny souvisejících testů se dají spouště také dohromady pro zdokonalené ladění. Stačí spustit testovací spustitelný soubor s argumentem <cmd>-p</cmd>: <cmd>./název-testovací-sady -p /cesta/k/testovací/skupině</cmd>.

note: (itstool) path: section/title
en: Installed Tests
cs: Nainstalované testy

note: (itstool) path: section/p
en: All unit tests should be installed system-wide, following the <link href="https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests">installed-tests standard</link>.
cs: Všechny jednotkové testy by měly být nainstalovány celosystémově s dodržením <link href="https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests">standardů pro instalaci testů</link>.

note: (itstool) path: section/p
en: By installing the unit tests, continuous integration (CI) is made easier, since tests for one project can be re-run after changes to other projects in the CI environment, thus testing the interfaces between modules. That is useful for a highly-coupled set of projects like GNOME.
cs: Instalací jednotkových testů se zjednoduší průběžná začleňování, protože testy pro jeden projekt je možné spustit znovu po změnách v jiném projektu v průběžně začleňovaném prostředí, a tím testovat rozhraní mezi moduly. To je užitečné hlavně pro hodně provázané sady projektů, jako je tomu v GNOME.

note: (itstool) path: section/p
en: To add support for installed-tests, add the following to <file>configure.ac</file>:
cs: Když chcete přidat podporu pro instalované testy, přidejte do <file>configure.ac</file> následující:

note: (itstool) path: section/p
en: Then in <file>tests/Makefile.am</file>:
cs: A potom do <file>tests/Makefile.am</file>:

note: (itstool) path: section/title
en: Leak Checking
cs: Kontrola úniků

note: (itstool) path: section/p
en: Once unit tests with high code coverage have been written, they can be run under various dynamic analysis tools, such as <link xref="tooling#valgrind">Valgrind</link> to check for leaks, threading errors, allocation problems, etc. across the entire code base. The higher the code coverage of the unit tests, the more confidence the Valgrind results can be treated with. See <link xref="tooling"/> for more information, including build system integration instructions.
cs: Jakmile napíšete jednotkové testy pokrývající velkou část kódu, můžete je spouštět pod různými dynamickými analytickými nástroji, jako je <link xref="tooling#valgrind">Valgrind</link>, abyste zkontrolovali úniky, chyby vláken, problémy s alokací apod. napříč celým zdrojovým kódem. Čím vyšší je pokrytí kódu jednotkovými testy, tím je možné výsledky z Valgrindu brát jako důvěryhodnější. Více informací viz <link xref="tooling"/>, včetně návodu na integraci do sestavovacího systému.

note: (itstool) path: section/p
en: Critically, this means that unit tests should not leak memory or other resources themselves, and similarly should not have any threading problems. Any such problems would effectively be false positives in the analysis of the actual project code. (False positives which need to be fixed by fixing the unit tests.)
cs: Podstatné je, že jednotkové testy by neměly samy o sobě způsobovat uniky paměti nebo jiných prostředků a stejně tak způsobovat problémy s vlákny. Jakékoliv takové problémy by ve skutečnosti způsobovaly falešná pozitivní hlášení v analýzách reálného kódu projektu. (Falešná pozitivní hlášení, která musí být opravena opravou jednotkových testů.)

note: (itstool) path: section/title
en: Test Generation
cs: Generování testů

note: (itstool) path: section/p
en: Certain types of code are quite repetitive, and require a lot of unit tests to gain good coverage; but are appropriate for <link href="https://en.wikipedia.org/wiki/Test_data_generation">test data generation</link>, where a tool is used to automatically generate test vectors for the code. This can drastically reduce the time needed for writing unit tests, for code in these specific domains.
cs: Některé formy kódu se dost často opakují a vyžadují hodně jednotkových testů, aby byly dobře pokryty. Na druhou stranu jsou ale vhodné pro <link href="https://en.wikipedia.org/wiki/Test_data_generation">generování testovacích dat</link> a na to existují nástroje, které pro kód automaticky vygenerují testovací vektory. Tím se výrazně sníží čas potřebný pro psaní jednotkových testů pro kód v této konkrétní oblasti.

note: (itstool) path: section/p
en: One example of a domain amenable to test data generation is parsing, where the data to be parsed is required to follow a strict schema — this is the case for XML and JSON documents. For JSON, a tool such as <link href="http://people.collabora.com/~pwith/walbottle/">Walbottle</link> can be used to generate test vectors for all types of valid and invalid input according to the schema.
cs: Jedním z příkladů domény, vůči níž se testuje generování dat, je jejich zpracování v případech, kdy se očekává dodržení striktního schématu dat. To je případ dokumentů XML a JSON. Pro JSON lze použít <link href="http://people.collabora.com/~pwith/walbottle/">Walbottle</link> pro vygenerování testovacích vektorů pro všechny typy platných i neplatných vstupů odpovídajících schématu.

note: (itstool) path: section/p
en: Every type of JSON document should have a <link href="http://json-schema.org/">JSON Schema</link> defined for it, which can then be passed to Walbottle to generate test vectors:
cs: Všechny typy dokumentů JSON by k tomu měly mít definováno <link href="http://json-schema.org/">schéma JSON</link>, které můžete předat do Walbottle, aby vygeneroval testovací vektory:

note: (itstool) path: section/code
en: 
    json-schema-generate --valid-only schema.json
    json-schema-generate --invalid-only schema.json
cs: 
    json-schema-generate --valid-only schéma.json
    json-schema-generate --invalid-only schéma.json

note: (itstool) path: section/p
en: These test vectors can then be passed to the code under test in its unit tests. The JSON instances generated by <cmd>--valid-only</cmd> should be accepted; those from <cmd>--invalid-only</cmd> should be rejected.
cs: Tyto testovací vektory je pak možné předat kódu právě testovanému v jeho jednotkových testech. Instance JSON vygenerované pomocí <cmd>--valid-only</cmd> by měly být přijaty, zatímco ty vygenerované pomocí <cmd>--invalid-only</cmd> odmítnuty.

note: (itstool) path: section/title
en: Writing Testable Code
cs: Psaní testovatelného kódu

note: (itstool) path: section/p
en: Code should be written with testability in mind from the design stage, as it affects API design and architecture in fundamental ways. A few key principles:
cs: Při psaní kódu by se mělo myslet na jeho testovatelnost už ve fázi návrhu, protože to zásadním způsobem ovlivňuje návrh API a architekturu. Zde je několik klíčových principů:

note: (itstool) path: item/p
en: Do not use global state. Singleton objects are usually a bad idea as they can’t be instantiated separately or controlled in the unit tests.
cs: Nepoužívejte globální stavy. Unikátní objekty (singletony) jsou většinou špatný nápad, protože pro ně nelze vytvářet oddělené instance nebo je řídit v jednotkových testech.

note: (itstool) path: item/p
en: Separate out use of external state, such as databases, networking, or the file system. The unit tests can then replace the accesses to external state with mocked objects. A common approach to this is to use dependency injection to pass a file system wrapper object to the code under test. For example, a class should not load a global database (from a fixed location in the file system) because the unit tests would then potentially overwrite the running system’s copy of the database, and could never be executed in parallel. They should be passed an object which provides an interface to the database: in a production system, this would be a thin wrapper around the database API; for testing, it would be a mock object which checks the requests given to it and returns hard-coded responses for various tests.
cs: Oddělte používání vnějších stavů, jako jsou databáze, sítě nebo souborové systémy. Jednotkové testy je pak mohou nahradit přístupem k vnějšímu stavu s falešným objektem. Společným přístupem k tomu je použít vnucování závislostí, které předají objekt obalující souborový systém kódu, který je právě testován. Například třída by neměla načítat globální databázi (z pevně daného místa v souborovém systému), protože jednotkové testy by pak potenciálně mohly přepsat běžící systémovou kopii databáze a nikdy by nemohly být spuštěny souběžně. Měly by být předáván objekt, který poskytne rozhraní k databázi. V produkčním systému to bude tenké obalení okolo databázového API, při testování by to pak mohl být pokusný objekt, který kontroluje požadavky, které mu jsou předávány a vrací pevně dané odpovědi pro různorodé testy.

note: (itstool) path: item/p
en: Expose utility functions where they might be generally useful.
cs: Vystavte pomocné funkce, pokud mohou být obecně užitečné.

note: (itstool) path: item/p
en: Split projects up into collections of small, private libraries which are then linked together with a minimal amount of glue code into the overall executable. Each can be tested separately.
cs: Rozdělte projekt do sady malých privátních knihoven, které pak propojíte dohromady minimálním množstvím spojovacího kódu, aby tak vznikl spustitelný celek. Každou pak můžete testovat odděleně.

note: (itstool) path: section/p
en: The topic of software testability is covered in the following articles:
cs: Tématem testovatelnosti softwaru se zabývají následující články:

note: (itstool) path: item/p
en: <link href="https://en.wikipedia.org/wiki/Dependency_injection">Dependency injection</link>
cs: <link href="https://cs.wikipedia.org/wiki/Vkládání_závislostí">Vkládání závislostí</link>

note: (itstool) path: info/desc
en: Source code version control with git
cs: Správa verzí zdrojového kódu pomocí git

note: (itstool) path: page/title
en: Version Control
cs: Správa verzí

note: (itstool) path: synopsis/p
en: git is used for version control for all GNOME projects. This page assumes good working knowledge of git; some introductory material is available <link href="https://www.atlassian.com/git/tutorials/">here</link>, and a <link href="https://training.github.com/kit/downloads/github-git-cheat-sheet.pdf">git cheatsheet is here</link>.
cs: Pro správu verzí se u všech projektů GNOME používá Git. Tato stránka předpokládá dobrou znalost práce se systémem git. Materiály pro úvod do této problematiky najdete <link href="https://www.atlassian.com/git/tutorials/">zde</link> a <link href="https://training.github.com/kit/downloads/github-git-cheat-sheet.pdf">přehledný tahák zde</link>. V češtině je volně k dispozici <link href="https://knihy.nic.cz/">překlad knihy Pro Git</link>.

note: (itstool) path: item/p
en: Make atomic, revertable commits. (<link xref="#guidelines-for-making-commits"/>)
cs: Vytvářejte atomická zařazení, která jdou vzít zpět. (<link xref="#guidelines-for-making-commits"/>)

note: (itstool) path: item/p
en: Include full reasoning in commit messages, plus links to relevant bug reports or specifications. (<link xref="#guidelines-for-making-commits"/>)
cs: Do zprávy k zařazení uveďte jeho plný důvod, plus odkazy na příslušná chybová hlášení nebo specifikace. (<link xref="#guidelines-for-making-commits"/>)

note: (itstool) path: item/p
en: Keep large changes, such as renames, in separate commits. (<link xref="#guidelines-for-making-commits"/>)
cs: Rozsáhlé změny, jako třeba přejmenování, zařazujte zvlášť. (<link xref="#guidelines-for-making-commits"/>)

note: (itstool) path: item/p
en: Merge changes from feature branches by rebasing. (<link xref="#use-of-git"/>)
cs: Slučujte změny z větví pro nové funkce pomocí přeskládání. (<link xref="#use-of-git"/>)

note: (itstool) path: section/title
en: Use of Git
cs: Používání správy verzí Git

note: (itstool) path: section/p
en: Most GNOME repositories follow these rules:
cs: Většina repozitářů GNOME dodržuje tato následující pravidla:

note: (itstool) path: item/p
en: No forced pushes. Except for branches with the <code>wip/</code> prefix (work-in-progress), the commits’ history must not be modified, as contributors rely on it.
cs: Nepoužívejte nahrávání s parametrem „force“. Vyjma větví s prefixem <code>wip/</code> (work-in-progres) pro rozpracované věci, se nesmí historie zařazení měnit, protože přispěvatelé na ni spoléhají.

note: (itstool) path: item/p
en: Rebase commits rather than merging, to have a linear history (which is easier to follow).
cs: Používejte přeskládání (rebase) místo slučování (merge), aby historie byla lineární (je to přehlednější pro sledování).

note: (itstool) path: item/p
en: Work on feature branches on GNOME git in <code>wip/</code> branches, then rebase on master and fast-forward merge the changes. It is a good practice to also add your nickname to the branch name, as <code>wip/nickname/feature</code>.
cs: Větve, ve kterých pracujete na nových funkcích GNOME, umisťujte v Gitu do větve <code>wip/</code>, pak přeskládejte hlavní větev a změny slučte rychle vpřed (fast-forward merge). Je také dobrým zvykem přidat do názvu větve svoji přezdívku, nějak jako <code>wip/prezdivka/funkce</code>.

note: (itstool) path: item/p
en: Hide <link href="https://sethrobertson.github.io/GitBestPractices/#sausage">sausage making</link> by squashing commits before merging.
cs: Před sloučením skryjte <link href="https://sethrobertson.github.io/GitBestPractices/#sausage">vytvořený guláš</link> pomocí komprimace (squash).

note: (itstool) path: section/title
en: Guidelines for Making Commits
cs: Pokyny pro vytváření zařazení

note: (itstool) path: section/p
en: Commits should be as small as possible, but no smaller. Each commit should address a single issue, containing only changes related to that issue. The message for each commit should describe the issue, explain what causes it, and explain how it has been fixed if it is not obvious. If the commit is associated with a bug report, the full URI for the bug report should be put on a line by itself at the bottom of the commit message. Similarly, the ID for the git commit (from <cmd>git log --oneline</cmd>) should be copied into the bug report once the commit has been pushed, so it is easy to find one from the other.
cs: Jednotlivá zařazení by měla být co nejmenší je rozumné, ale ne menší. Každé zařazení se má zabývat jediným problémem a obsahovat jen změny vztahující se k tomuto problému. Zpráva u jednotlivých zařazení by pak měla obsahovat popis onoho problému, vysvětlit co způsobuje a vysvětlit jak byl opraven, pokud to není očividné. Pokud se k problému vztahuje chybové hlášení, měla by se na konec zprávy na samostatný řádek vložit úplná adresa URI tohoto hlášení. A naopak, do chybového hlášení by se mělo nakopírovat ID zařazení (z <cmd>git log --oneline</cmd>), aby bylo jednoduché obě věci navzájem dohledat.

note: (itstool) path: section/p
en: The changes in each commit should be easy to read. For example, they should not unnecessarily change whitespace or indentation. Large, mechanical changes, such as renaming a file or function, should be put in separate commits from modifications to code inside that file or function, so that the latter changes do not get buried and lost in the former.
cs: Změny v jednotlivých zařazeních by měly být snadno čitelné. Například by neměly obsahovat samoúčelné změny v bílých znacích nebo odsazení. Rozsáhlé mechanické změny, jako je přejmenování souborů nebo funkcí, by měly být v samostatném zařazení, odděleně od změn v kódu v souboru nebo funkci, takže pozdější změny někam nezapadnou a nebudou ztraceny v prvním jmenovaném případě.

note: (itstool) path: section/p
en: The following principles give the reasoning for all the advice above:
cs: Důvodem pro všechny uvedené rady jsou následující principy:

note: (itstool) path: item/p
en: Each commit should take the repository from one working state to another, otherwise <link href="http://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git#Binary-Search">bisection</link> is impossible.
cs: Každé zařazení by mělo dostat repozitář z jednoho plně funkčního stavu do dalšího plně funkčního stavu, jinak znemožníte použití <link href="http://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git#Binary-Search">binárního vyhledávání příkazem bisect</link>.

note: (itstool) path: item/p
en: Each commit should be individually revertable. If it later turns out that the commit was a bad idea, <cmd>git revert <var>commit ID</var></cmd> should take the repository from a working state to another working state.
cs: Každé zařazení by mělo jít samostatně vzít zpět. Když se později zjistí, že zařazení nebylo dobrým nápadem, měl by příkaz <cmd>git revert <var>ID zařazení</var></cmd> převést repozitář z jednoho plně funkčního stavu do jiného plně funkčního stavu.

note: (itstool) path: item/p
en: The reasoning for each commit, and its relationship to external resources like specifications and bug reports, should be clear, to the extent that commits written by one developer a year in the past should still be understandable by a second developer without having to trace through the changes and work out what they do.
cs: Důvod každého zařazení a jeho vztah k externím prostředkům, jako je zadání nebo nahlášená chyba, by měly být jasné do té míry, že zařazení, které napsal jeden vývojář před rokem, pochopí hned i jiný vývojář, bez zdlouhavého procházení změn a studování, co dělají.

note: (itstool) path: item/p
en: Each commit should be written once, and designed to be read many times, by many reviewers and future programmers.
cs: Každé zařazení by mělo být napsáno jednou naráz, ale navrženo s tím, že čteno může být nesčetněkrát, mnoha lidmi provádějícimi kontrolu a budoucími programátory.

note: (itstool) path: section/title
en: Merging Procedure
cs: Slučovací procedura

note: (itstool) path: section/p
en: To merge a feature branch named <code>my-branch</code> into master, use the following commands:
cs: Pro sloučení větve s novou funkcionalitou, pojmenované <code>my-branch</code>, do hlavní větve použijte následující příkazy:

note: (itstool) path: section/code
en: 
    git checkout master
    git pull
    
    git checkout wip/<var>my-branch</var>
    git rebase --interactive master
    # Ensure the rebase is successful; test the changes
    
    git checkout master
    git merge wip/<var>my-branch</var>
    git push
    
    # wip/<var>my-branch</var> can now be deleted
    git push origin :wip/<var>my-branch</var>
    git branch -D wip/<var>my-branch</var>
cs: 
    git checkout master
    git pull
    
    git checkout wip/<var>my-branch</var>
    git rebase --interactive master
    # Kontrola úspěšnosti přeskládání, test změn
    
    git checkout master
    git merge wip/<var>my-branch</var>
    git push
    
    # wip/<var>my-branch</var> lze nyní smazat
    git push origin :wip/<var>my-branch</var>
    git branch -D wip/<var>my-branch</var>

note: (itstool) path: info/desc
en: Versioning and releasing libraries and applications
cs: Číslování verzí a vydávání knihoven a aplikací

note: (itstool) path: synopsis/p
en: Module versioning differs for libraries and applications: libraries need a libtool version specified in addition to their package version. Applications just have a package version.
cs: Číslování verzí se liší pro knihovny a pro aplikace: knihovny potřebují mít mimo čísla verze pro balíček určené i číslo verze pro libtool. Aplikace mají jen číslo verze pro balíček.

note: (itstool) path: item/p
en: Libraries and applications have a package version of the form <em>major.minor.micro</em>. (<link xref="#package-versioning"/>)
cs: Knihovny a aplikace mají čísla verzí balíčků ve formě <em>hlavní.vedlejší.setinkové</em>. (<link xref="#package-versioning"/>)

note: (itstool) path: item/p
en: Libraries additionally have a libtool version of the form <em>current:revision:age</em>. (<link xref="#libtool-versioning"/>)
cs: Knihovny navíc mají číslo verze pro libtool ve formě <em>aktuální:revize:věk</em>. (<link xref="#libtool-versioning"/>)

note: (itstool) path: item/p
en: Version numbers should be updated for each release (using release and post-release increments). (<link xref="#release-process"/>)
cs: Číslo verze by mělo být aktualizováno u každého vydání (použijte zvýšení čísla při vydání a po vydání). (<link xref="#release-process"/>)

note: (itstool) path: item/p
en: Package versions should be incremented for feature changes or additions. (<link xref="#package-versioning"/>)
cs: Číslo verze balíčku by mělo být zvýšeno při změně nebo přidání funkcionality. (<link xref="#package-versioning"/>)

note: (itstool) path: item/p
en: Libtool versions should be updated for API changes or additions. (<link xref="#libtool-versioning"/>)
cs: Číslo verze libtool by mělo být aktualizováno při změnách nebo přidání API. (<link xref="#libtool-versioning"/>)

note: (itstool) path: item/p
en: Even/odd <em>minor</em> package versions can be used respectively for stable/unstable releases. (<link xref="#stable-unstable-versions"/>)
cs: Lichá/sudá <em>vedlejší</em> čísla verze balíčku mohou být použita k rozlišení stabilních/nestabilních vydání. (<link xref="#stable-unstable-versions"/>)

note: (itstool) path: section/title
en: Package Versioning
cs: Číslování verzí balíčků

note: (itstool) path: section/p
en: Both libraries and applications have a package version of the form <em>major.minor.micro</em>.
cs: Knihovny i aplikace mají čísla verzí balíčků ve formě <em>hlavní.vedlejší.setinkové</em> (<em>major.minor.micro</em>).

note: (itstool) path: section/p
en: The package version number is that passed to <code>AC_INIT()</code>, and the one which is typically known as the project’s version number. For example, the Debian package for a library will use the library’s package version (though may also include the major version number in the package name to allow for <link xref="parallel-installability">parallel installability</link>). Package versions are updated by the following rules:
cs: Číslo verze balíčku je to, které se předává do <code>AC_INIT()</code> a bývá známé jako číslo verze projektu. Například balíček ve formátu DEB (používaný distribucí Debian) pro knihovnu bude používat číslo verze balíčku s knihovnou (ačkoliv může v názvu balíčku obsahovat i hlavní číslo verze, aby se umožnila <link xref="parallel-installability">souběžná instalace</link>). Verze balíčku jsou aktualizovány podle následujících pravidel:

note: (itstool) path: item/p
en: If breaking <link xref="api-stability">API compatibility</link> in a library, or making a large change to an application which affects everything (such as a UI redesign), increment major and set minor and micro to 0.
cs: Při porušení <link xref="api-stability">kompatibility API</link> v knihovně nebo při provedení rozsáhlých změn v aplikaci, které ovlivní vše (třeba změna návrhu uživatelského rozhraní), zvyšte hlavní číslo verze a vedlejší a setinkové nastavte na 0.

note: (itstool) path: item/p
en: Otherwise, if changing or adding a feature, or adding any API, increment minor and set micro to 0.
cs: V ostatních případech, když měníte nebo přidáváte funkce nebo přidáváte nějaké API, zvyšte vedlejší číslo verze a setinkové nastavte na 0.

note: (itstool) path: item/p
en: Otherwise (if making a release containing only bug fixes and translation updates), increment micro.
cs: V ostatních případech (když vydání obsahuje jen opravy chyb a aktualizace překladů), zvyšte setinkové číslo verze.

note: (itstool) path: section/p
en: Note that the minor version number should be updated if any API is added.
cs: Nezapomeňte, že vedlejší číslo verze by mělo být aktualizováno, když je přidáno nějaké API.

note: (itstool) path: section/title
en: Libtool Versioning
cs: Čísla verzí pro Libtool

note: (itstool) path: section/p
en: Libraries have two version numbers: a libtool version which tracks ABI backwards compatibility (see <link xref="api-stability"/>), and a package version which tracks feature changes. These are normally incremented in synchronization, but should be kept separate because ABI backwards compatibility is not necessarily related to feature changes or bug fixes. Furthermore, the two version numbers have different semantics, and cannot be automatically generated from each other.
cs: Knihovny mají dvě čísla verze: verzi libtool, která sleduje zpětnou kompatibilitu ABI (viz <link xref="api-stability"/>) a číslo verze balíčku, které sleduje změny vlastností. Normálně jsou zvyšovány současně, ale měly by se udržovat oddělené, protože zpětná kompatibilita ABI nemusí nutně souviset se změnami vlastností nebo opravami chyb. Navíc tato dvě číslování mají rozdílnou sémantiku a není tak možné vygenerovat jedno na základě druhého.

note: (itstool) path: section/p
en: A good overview of libtool versioning, and the differences from package versioning, is given in the <link href="https://autotools.io/libtool/version.html">Autotools Mythbuster</link>; another is in the <link href="http://www.gnu.org/s/libtool/manual/html_node/Updating-version-info.html">libtool manual</link>.
cs: Dobrý přehled o číslování verzí libtool a o rozdílech oproti číslování verzí balíčků najdete v článku <link href="https://autotools.io/libtool/version.html">Autotools Mythbuster</link>, a případně také v <link href="http://www.gnu.org/s/libtool/manual/html_node/Updating-version-info.html">příručce k libtool</link>.

note: (itstool) path: section/p
en: To update the libtool version, follow the algorithm given in the comments below. This is a typical <file>configure.ac</file> snippet for setting up libtool versioning:
cs: Při aktualizaci verze libtool postupujte podle algoritmu uvedeném v komentářích níže. Jedná se o typický úryvek z <file>configure.ac</file> pro nastavení verze libtool:

note: (itstool) path: section/code
en: 
    # Before making a release, the LT_VERSION string should be modified. The
    # string is of the form c:r:a. Follow these instructions sequentially:
    #   1. If the library source code has changed at all since the last update, then
    #      increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
    #   2. If any interfaces have been added, removed, or changed since the last
    #      update, increment current, and set revision to 0.
    #   3. If any interfaces have been added since the last public release, then
    #      increment age.
    #   4. If any interfaces have been removed or changed since the last public
    #      release, then set age to 0.
    AC_SUBST([LT_VERSION],[0:0:0])
cs: 
    # Před vydáním by se měl upravit řetězec LT_VERSION, který je ve formě a:r:v
    # (aktuální:revize:věk). Postupujte podle následujících bodů:
    #   1. Když od poslední aktualizace došlo ke změně zdrojového kódu knihovny
    #      jako celku, zvyšte revizi („a:r:v“ se změní na „a:r+1:v“).
    #   2. Když bylo od poslední aktualizace přidáno, odebráno nebo změněno
    #      rozhraní, zvyšte aktuální a revizi nastavte na 0.
    #   3. Když bylo od posledního veřejného vydání přidáno rozhraní, zvyšte věk.
    #   4. Když bylo od posledního veřejného vydání odebráno nebo změněno 
    #      rozhraní, nastavte věk na 0.
    AC_SUBST([LT_VERSION],[0:0:0])

note: (itstool) path: section/p
en: The following snippet can be used in a <file>Makefile.am</file> to pass that version info to libtool:
cs: Následující úryvek můžete použít v souboru <file>Makefile.am</file> k předání informace o verzi do libtool:

note: (itstool) path: section/title
en: Stable and Unstable Package Versions
cs: Stabilní a nestabilní verze balíčku

note: (itstool) path: section/p
en: Most GNOME modules follow a convention for stable and unstable releases. The minor version is even for stable releases and is odd for unstable releases. For example, the 3.20.* versions are stable, but the 3.19.* versions are unstable. The 3.19.* versions can be seen as alpha and beta releases of the 3.20 version.
cs: Většina modulů GNOME dodržuje zvyklost stabilních a nestabilních vydání. Vedlejší číslo verze je sudé pro stabilní vydání a liché pro nestabilní vydání. Například verze 3.20.* jsou stabilní, ale 3.19.* nestabilní. Na verze 3.19.* můžete pohlížet jako na alfa a beta vydání pro verzi 3.20.

note: (itstool) path: section/p
en: A new micro <em>stable</em> version (e.g. 3.20.0 → 3.20.1) doesn’t add new features, only translation updates and bug fixes. On the other hand, <em>unstable</em> micro releases (e.g. 3.19.1 → 3.19.2) can add API, or change or remove API which was added in a previous micro release in that minor series.
cs: Nové setinkové <em>stabilní</em> verze (např. 3.20.0 → 3.20.1) nepřidávají nové funkce, ale jen aktualizace překladů a opravy chyb. Naproti tomu, <em>nestabilní</em> setinkové verze (např. 3.19.1 → 3.19.2) mohou přidat API nebo změnit nebo odstranit API, které bylo přidáno v předchozí setinkové verzi stejné vedlejší série.

note: (itstool) path: section/p
en: The libtool version should be updated only for stable package versions.
cs: Číslo verze pro libtool by mělo být aktualizováno jen pro stabilní verzi balíčku.

note: (itstool) path: section/title
en: Release Process
cs: Proces vydání

note: (itstool) path: section/p
en: The standard process for making a release of a module increments the libtool version (if the module is a library) at the time of release, then increments the package version number immediately afterwards (this is called a post-release increment).
cs: Standardní proces tvorby vydání modulu zvyšuje v průběhu vydání číslo verze pro libtool (pokud je modul knihovnou) a bezprostředně po té zvýší číslo verze balíčku (tzv. post-release zvýšení).

note: (itstool) path: section/p
en: Updating the libtool versions at the time of release means that they are only incremented once for all ABI changes in a release. The use of post-release increment for package versions means the package version number is not outdated (still equal to the previous release) during the development cycle.
cs: Aktualizace verze libtool v době vydání znamená, že je zvýšena jen jednou naráz pro všechny změny ABI ve vydání. Použití zvýšení po vydání pro číslo verze balíčku znamená, že číslo verze balíčku nebude zastaralé (pořád stejné jako u předchozího vydání) během vývojového cyklu.

note: (itstool) path: section/p
en: The release process (based on the <link href="https://wiki.gnome.org/MaintainersCorner/Releasing">GNOME release process</link>):
cs: Proces vydání (vycházející z <link href="https://wiki.gnome.org/MaintainersCorner/Releasing">procesu vydávání GNOME</link>):

note: (itstool) path: item/p
en: Make sure code is up to date: <cmd>git pull</cmd>
cs: Zkontrolujte, že je kód aktuální: <cmd>git pull</cmd>

note: (itstool) path: item/p
en: Make sure you have no local changes: <cmd>git status</cmd>
cs: Zkontrolujte, že nemáte provedené žádné místní změny: <cmd>git status</cmd>

note: (itstool) path: item/p
en: If the release is for a stable package version, increment the libtool version number in <file>configure.ac</file> (if it exists)
cs: V případě, že se jedná o vydání pro stabilní verzi balíčku, zvyšte číslo verze pro libtool v <file>configure.ac</file> (pokud existuje)

note: (itstool) path: item/p
en: Add an entry to the <file>NEWS</file> file
cs: Přidejte záznam do souboru <file>NEWS</file>

note: (itstool) path: item/p
en: Run <cmd>./autogen.sh &amp;&amp; make &amp;&amp; make install &amp;&amp; make distcheck</cmd> and ensure it succeeds
cs: Spusťe <cmd>./autogen.sh &amp;&amp; make &amp;&amp; make install &amp;&amp; make distcheck</cmd> a ověřte, že vše proběhlo v pořádku

note: (itstool) path: item/p
en: Fix any issues which come up, commit those changes, and restart at step 3
cs: Opravte případné problémy, které nastaly, zařaďte je a vraťte se ke kroku 3

note: (itstool) path: item/p
en: If <cmd>make distcheck</cmd> finishes with “[archive] is ready for distribution”, run <cmd>git commit -a -m "Release version x.y.z"</cmd> (where ‘x.y.z’ is the package version number)
cs: Pokud <cmd>make distcheck</cmd> skončí s „[archive] is ready for distribution“, spusťte <cmd>git commit -a -m "Release version x.y.z"</cmd> (kde „x.y.z“ je číslo verze balíčku)

note: (itstool) path: item/p
en: Run <cmd>git push</cmd>
cs: Spusťte <cmd>git push</cmd>

note: (itstool) path: item/p
en: If that fails due to other commits having been pushed in the meantime, run <cmd>git pull</cmd> to merge your commit on the branch followed by a second <cmd>git push</cmd>. This is an exception to the GNOME guideline to have a linear Git history (<link xref="version-control#use-of-git"/>). If you prefer to have a linear history, you need to restart at step 1.
cs: Pokud to selže, protože během správy byly nahrány další zařazení, spusťte <cmd>git pull</cmd>, aby se sloučily vaše zařazení s větví následovanou po druhém <cmd>git push</cmd>. Jedná se o výjimku oproti pokynům GNOME, které říkají, že máte mít v Git lineární historii (<link xref="version-control#use-of-git"/>). Pokud dáváte lineární historii přednost, musíte se vrátit ke kroku 1.

note: (itstool) path: item/p
en: Tag the release: <cmd>git tag -s x.y.z</cmd> (where ‘x.y.z’ is the package version number)
cs: Přidělte vydání štítek: <cmd>git tag -s x.y.z</cmd> (kde „x.y.z“ je číslo verze balíčku)

note: (itstool) path: item/p
en: Run <cmd>git push origin x.y.z</cmd> (where ‘x.y.z’ is the package version number)
cs: Spusťte <cmd>git push origin x.y.z</cmd> (kde „x.y.z“ je číslo verze balíčku)

note: (itstool) path: section/p
en: The release is now complete, and the post-release version increment can be done:
cs: Vydání je nyní hotové a můžete provést (post-release) zvýšení čísla verze pro následující vydání:

note: (itstool) path: item/p
en: Increment the package version number in <file>configure.ac</file>
cs: Zvyšte číslo verze balíčku v <file>configure.ac</file>

note: (itstool) path: item/p
en: Run <cmd>git commit -a -m "Post-release version increment"</cmd>
cs: Spusťte <cmd>git commit -a -m "Post-release version increment"</cmd>

note: (itstool) path: section/p
en: The package archive generated by <cmd>make distcheck</cmd> can now be uploaded to download.gnome.org or distributed in other ways.
cs: Balíček vygenerovaný pomocí <cmd>make distcheck</cmd> může být nyní nahrán na download.gnome.org nebo šířen nějakým jiným způsobem.

note: (itstool) path: info/desc
en: Good, readable code keeps the project maintainable
cs: Kvalitní a čitelný kód zajišťuje udržovatelnost projektu

note: (itstool) path: page/title
en: The Importance of Writing Good Code
cs: Význam psaní kvalitního kódu

note: (itstool) path: page/p
en: GNOME is a very ambitious free software project, and it is composed of many software packages that are more or less independent of each other. A lot of the work in GNOME is done by volunteers: although there are many people working on GNOME full-time or part-time for here, volunteers still make up a large percentage of our contributors. Programmers may come and go at any time and they will be able to dedicate different amounts of time to the GNOME project. People’s “real world” responsibilities may change, and this will be reflected in the amount of time that they can devote to GNOME.
cs: GNOME je velmi ambiciózní svobodný softwarový projekt a skládá se z velkého množství softwarových balíčků, které jsou na sobě navzájem více či méně závislé. Většina práce na GNOME je prováděna dobrovolníky. Ačkoliv jsou i lidé, kteří na GNOME pracují placeně na plný nebo částečný úvazek, dobrovolníci zatím odvádějí největší díl práce ze všech přispěvatelů. Programátoři mohou přicházet a odcházet kdykoliv a věnovat projektu GNOME libovolné množství času. Lidem se mohou měnit podmínky ve „skutečném světě“ a to se odrazí v množství času, který mohou GNOME věnovat.

note: (itstool) path: page/p
en: Software development takes long amounts of time and painstaking effort. This is why most part-time volunteers cannot start big projects by themselves; it is much easier and more rewarding to contribute to existing projects, as this yields results that are immediately visible and usable.
cs: Vývoj softwaru zabírá hodně času a vyžaduje nemalé úsilí. To je důvod, proč dobrovolníci na částečný úvazek nemohou začít velké projekty vlastními silami. Je mnohem jednodušší, a přináší uspokojivější výsledky, přispět do stávajícího projektu. Výsledky jsou navíc ihned viditelné a použitelné.

note: (itstool) path: page/p
en: Thus, we conclude that it is very important for existing projects to make it as easy as possible for people to contribute to them. One way of doing this is by making sure that programs are easy to read, understand, modify, and maintain.
cs: Proto je jasné, že je velmi důležité u stávajících projektů zajistit, aby do nich lidé mohli přispívat jednoduše. Jedním ze způsobu, jak toho dosáhnout, je zajištění snadné čitelnosti, srozumitelnosti, úprav a správy.

note: (itstool) path: page/p
en: Messy code is hard to read, and people may lose interest if they cannot decipher what the code tries to do. Also, it is important that programmers be able to understand the code quickly so that they can start contributing with bug fixes and enhancements in a short amount of time. Source code is a form of <em>communication</em>, and it is more for people than for computers. Just as someone would not like to read a novel with spelling errors, bad grammar, and sloppy punctuation, programmers should strive to write good code that is easy to understand and modify by others.
cs: Škaredý kód se špatně čte a lidé mohou ztratit zájem, když nemohou rozluštit, o co se kód vlastně snaží. Je také důležité, aby byli programátoři schopni kód pochopit rychle a začít tak přispívat opravami chyb a vylepšeními ve velmi krátkém čase. Zdrojový kód je jistou formou <em>komunikace</em> a slouží spíše pro lidi, než pro počítače. Stejně, jako by se určitě nikomu nechtělo číst román plný překlepů, gramatických chyb a špatné interpunkce, i programátoři by měli usilovat o psaní kvalitního kódu, který je jednoduchý na pochopení a úpravy od ostatních.

note: (itstool) path: page/p
en: The following are some important qualities of good code:
cs: Následující věci jsou důležitými měřítky kvality dobrého kódu:

note: (itstool) path: item/title
en: Cleanliness
cs: Čistota

note: (itstool) path: item/p
en: Clean code is easy to read with minimum effort. This lets people start to understand it easily. This includes the coding style itself (brace placement, indentation, variable names), and the actual control flow of the code.
cs: Čistý kód se dobře čte, bez potřeby vynakládat na to nadměrné úsilí. Lidem to pomůže jej snadno pochopit. Patří k tomu přímo styl kódování (umístění závorek, odsazení, názvy proměnných) a vlatní řízení průběhu kódu.

note: (itstool) path: item/title
en: Consistency
cs: Jednotnost

note: (itstool) path: item/p
en: Consistent code makes it easy for people to understand how a program works. When reading consistent code, one subconsciously forms a number of assumptions and expectations about how the code works, so it is easier and safer to make modifications to it. Code that <em>looks</em> the same in two places should <em>work</em> the same, too.
cs: Jednotnost kódu usnadňuje lidem porozumět, jak program funguje. Když čtete konzistentní kód, podvědomě si utváříte řadu předpokladů a očekávání o tom, jak kód funguje, takže v něm jednodušeji a bezpečněji můžete provádět změny. Kód, který na dvou místech <em>vypadá</em> stejně, by měl i stejně <em>pracovat</em>.

note: (itstool) path: item/title
en: Extensibility
cs: Rozšiřitelnost

note: (itstool) path: item/p
en: General-purpose code is easier to reuse and modify than very specific code with lots of hardcoded assumptions. When someone wants to add a new feature to a program, it will obviously be easier to do so if the code was designed to be extensible from the beginning. Code that was not written this way may lead people into having to implement ugly hacks to add features.
cs: Kód s obecným účelem se snáze znovu použije a upraví, než velmi specifický kód s řadou natvrdo vložených předpokladů. Když chce někdo do programu přidat novou funkcionalitu, bude to mít samozřejmě jednodušší, když byl kód od začátku navrhován jako rozšiřitelný. Kód, který nebyl psán tímto způsobem, může vést lidi k použití různých nepěkných kliček, aby novou funkcionalitu mohli přidat.

note: (itstool) path: item/title
en: Correctness
cs: Správnost

note: (itstool) path: item/p
en: Finally, code that is designed to be correct lets people spend less time worrying about bugs, and more time enhancing the features of a program. Users also appreciate correct code, since nobody likes software that crashes. Code that is written for correctness and safety (i.e. code that explicitly tries to ensure that the program remains in a consistent state) prevents many kinds of silly bugs.
cs: No a konečně, programový kód, který je navržen tak, aby byl správný, nenutí lidi trávit čas trápením s řešením chyb a mohou tak více času věnovat vylepšování funkcionality programu. I uživatelé ocení správný kód, protože nikdo nemá rád software, který se hroutí. Kód, který je napsán správně a bezpečně (tj. kód, který se výslovně snaží zajistit, aby program setrval v konzistentním stavu) zabrání mnoha druhům nepříjemných chyb.

note: (itstool) path: section/title
en: Book References
cs: Doporučené knihy

note: (itstool) path: item/p
en: <link href="http://www.cc2e.com">Code Complete</link>, by Steve McConnell.
cs: <link href="http://www.cc2e.com">Code Complete</link> od autora Steve McConnell.

note: (itstool) path: item/p
en: <link href="http://martinfowler.com/books/refactoring.html"> Refactoring: Improving the Design of Existing Code </link>, by Martin Fowler.
cs: <link href="http://martinfowler.com/books/refactoring.html"> Refactoring: Improving the Design of Existing Code </link>, Martin Fowler.

note: (itstool) path: item/p
en: <link href="https://en.wikipedia.org/wiki/Design_Patterns"> Design Patterns: Elements of Reusable Object-Oriented Software </link>, by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides.
cs: <link href="https://en.wikipedia.org/wiki/Design_Patterns"> Design Patterns: Elements of Reusable Object-Oriented Software </link>, kolektiv autorů Erich Gamma, Richard Helm, Ralph Johnson a John Vlissides.

note: (itstool) path: item/p
en: <link href="http://astore.amazon.com/gnomestore-20/detail/020163385X"> Object-Oriented Design Heuristics </link>, by Arthur Riel.
cs: <link href="http://astore.amazon.com/gnomestore-20/detail/020163385X"> Object-Oriented Design Heuristics </link>, Arthur Riel.
