# Greek translation for gnome-devel-docs. # Copyright (C) 2016 gnome-devel-docs's COPYRIGHT HOLDER # This file is distributed under the same license as the gnome-devel-docs package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: gnome-devel-docs master\n" "POT-Creation-Date: 2017-01-17 20:12+0000\n" "PO-Revision-Date: 2016-03-17 14:24+0200\n" "Last-Translator: Tom Tryfonidis \n" "Language-Team: Greek \n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 1.8.7\n" #. Put one translator per line, in the form NAME , YEAR1, YEAR2 msgctxt "_" msgid "translator-credits" msgstr "" "Ελληνική μεταφραστική ομάδα GNOME , 2016\n" "Θάνος Τρυφωνίδης , 2016" #. (itstool) path: credit/name #: C/additional-materials.page:10 C/c-coding-style.page:10 #: C/documentation.page:11 C/index.page:8 C/writing-good-code.page:10 msgid "Federico Mena-Quintero" msgstr "Federico Mena-Quintero" #. (itstool) path: credit/years #: C/additional-materials.page:12 C/c-coding-style.page:12 #: C/documentation.page:13 C/index.page:10 C/writing-good-code.page:12 msgid "2013" msgstr "2013" #. (itstool) path: info/desc #: C/additional-materials.page:17 msgid "Other style guides and books about organizing free software projects" msgstr "" #. (itstool) path: page/title #: C/additional-materials.page:21 msgid "Additional Materials" msgstr "Επιπρόσθετο υλικό" #. (itstool) path: page/p #: C/additional-materials.page:23 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/additional-materials.page:32 msgid "" "Producing Open Source Software, by Karl Fogel. This is a truly excellent book of good practices that " "free software projects should follow. This is about social aspects " "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." msgstr "" #. (itstool) path: item/p #: C/additional-materials.page:46 msgid "" "GNU Coding Standards. 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." msgstr "" #. (itstool) path: item/p #: C/additional-materials.page:57 msgid "" " Linux Kernel Coding Style. Explains the rationale for \"big " "indentation\", brace placement, concise but unambiguous naming, and " "centralized exit of functions." msgstr "" #. (itstool) path: credit/name #: C/api-stability.page:10 C/databases.page:11 C/documentation.page:16 #: C/file-system.page:11 C/gerror.page:11 C/glist.page:11 C/index.page:21 #: C/introspection.page:10 C/logging.page:11 C/main-contexts.page:11 #: C/memory-management.page:10 C/namespacing.page:10 #: C/parallel-installability.page:18 C/preconditions.page:11 #: C/threading.page:11 C/tooling.page:10 C/unit-testing.page:10 #: C/version-control.page:10 C/versioning.page:10 msgid "Philip Withnall" msgstr "Philip Withnall" #. (itstool) path: credit/years #: C/api-stability.page:12 C/databases.page:13 C/documentation.page:18 #: C/file-system.page:13 C/gerror.page:13 C/glist.page:13 C/index.page:23 #: C/introspection.page:12 C/logging.page:13 C/memory-management.page:12 #: C/parallel-installability.page:20 C/preconditions.page:13 #: C/threading.page:13 C/tooling.page:12 C/unit-testing.page:12 #: C/version-control.page:12 C/versioning.page:12 msgid "2015" msgstr "2015" #. (itstool) path: info/desc #: C/api-stability.page:17 #, fuzzy msgid "Backwards compatibility in APIs" msgstr "Συμβατότητα" #. (itstool) path: page/title #: C/api-stability.page:20 msgid "API stability" msgstr "Σταθερότητα API" #. (itstool) path: synopsis/title #: C/api-stability.page:23 C/databases.page:24 C/documentation.page:32 #: C/file-system.page:24 C/introspection.page:23 C/logging.page:26 #: C/main-contexts.page:27 C/memory-management.page:65 C/namespacing.page:25 #: C/parallel-installability.page:33 C/threading.page:24 C/tooling.page:45 #: C/unit-testing.page:23 C/version-control.page:23 C/versioning.page:23 msgid "Summary" msgstr "Σύνοψη" #. (itstool) path: item/p #: C/api-stability.page:26 msgid "" "Define API stability guarantees for your project. ()" msgstr "" #. (itstool) path: item/p #: C/api-stability.page:30 msgid "" "Ensure version numbers are changed as appropriate when API changes. ()" msgstr "" #. (itstool) path: section/title #: C/api-stability.page:38 msgid "API and ABI" msgstr "API και ABI" #. (itstool) path: section/p #: C/api-stability.page:40 msgid "" "At a high level, an API – Application Programming Interface – is " "the boundary between two components when developing against them. It is " "closely related to an ABI – Application Binary Interface – 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 #defines, 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." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:54 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:59 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:67 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/api-stability.page:75 msgid "Stability" msgstr "Σταθερότητα" #. (itstool) path: section/p #: C/api-stability.page:77 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:93 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:102 msgid "Several types of stability commonly considered:" msgstr "" #. (itstool) path: item/title #: C/api-stability.page:107 #, fuzzy msgid "Unstable" msgstr "Μη σταθερή" #. (itstool) path: item/p #: C/api-stability.page:108 msgid "The API could change or be removed in future." msgstr "" #. (itstool) path: item/title #: C/api-stability.page:111 #, fuzzy msgid "Backwards compatible" msgstr "Αναζήτηση προς τα _πίσω" #. (itstool) path: item/p #: C/api-stability.page:112 msgid "" "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)." msgstr "" #. (itstool) path: item/title #: C/api-stability.page:119 #, fuzzy msgid "Forwards compatible" msgstr "Απαντήσεις και προωθήσεις" #. (itstool) path: item/p #: C/api-stability.page:120 msgid "" "Only changes which permit code compiled against the modified API to run " "against the unmodified API are allowed (for example, functions cannot be " "added)." msgstr "" #. (itstool) path: item/title #: C/api-stability.page:127 #, fuzzy msgid "Totally stable" msgstr "Σταθερή" #. (itstool) path: item/p #: C/api-stability.page:128 msgid "No changes are allowed to the API, only to the implementation." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:132 msgid "" "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." msgstr "" #. (itstool) path: section/title #. (itstool) path: page/title #: C/api-stability.page:140 C/versioning.page:20 #, fuzzy msgid "Versioning" msgstr "Εκδόσεις" #. (itstool) path: section/p #: C/api-stability.page:142 msgid "" "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 Autotools Mythbuster or ." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:151 msgid "" "Package versioning (major.minor.micro) 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 " "for more information." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:162 msgid "" "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 documentation on D-" "Bus API versioning for details." msgstr "" #. (itstool) path: section/p #: C/api-stability.page:169 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/api-stability.page:179 C/unit-testing.page:272 C/version-control.page:161 msgid "External Links" msgstr "Εξωτερικοί σύνδεσμοι" #. (itstool) path: section/p #: C/api-stability.page:181 msgid "The topic of API stability is covered in the following articles:" msgstr "" #. (itstool) path: item/p #: C/api-stability.page:185 msgid "" "Wikipedia page on APIs" msgstr "" #. (itstool) path: item/p #: C/api-stability.page:189 msgid "" "Wikipedia page on ABIs" msgstr "" #. (itstool) path: item/p #: C/api-stability.page:193 msgid "" "D-Bus API versioning documentation" msgstr "" #. (itstool) path: credit/name #: C/c-coding-style.page:15 C/documentation.page:21 msgid "The GTK+ Team" msgstr "Η ομάδα GTK+" #. (itstool) path: info/desc #: C/c-coding-style.page:20 msgid "Our guidelines for C code in GNOME" msgstr "Οι οδηγίες μας για κώδικα C στο GNOME" #. (itstool) path: page/title #: C/c-coding-style.page:23 msgid "C Coding Style" msgstr "Στυλ κώδικα C" #. (itstool) path: page/p #: C/c-coding-style.page:25 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/c-coding-style.page:32 msgid "" "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!" msgstr "" #. (itstool) path: note/p #: C/c-coding-style.page:42 msgid "" "This document is for C code. For other languages, check the main page of the GNOME Programming Guidelines." msgstr "" #. (itstool) path: page/p #: C/c-coding-style.page:49 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/c-coding-style.page:58 msgid "The Single Most Important Rule" msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:60 msgid "" "The single most important rule when writing code is this: check the " "surrounding code and try to imitate it." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:65 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:72 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/c-coding-style.page:80 msgid "Line Width" msgstr "Πλάτος γραμμής" #. (itstool) path: section/p #: C/c-coding-style.page:82 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/c-coding-style.page:93 msgid "Indentation" msgstr "Εσοχή" #. (itstool) path: section/p #: C/c-coding-style.page:95 msgid "" "In general there are two preferred indentation styles for code in GNOME." msgstr "Γενικά υπάρχουν δύο προτεινόμενα στυλ εσοχής κώδικα για το GNOME." #. (itstool) path: item/p #: C/c-coding-style.page:102 msgid "" "Linux Kernel style. Tabs with a length of 8 characters are used for the " "indentation, with K&R brace placement:" msgstr "" "Το στυλ Linux Kernel. Στηλοθέτες με μήκος 8 χαρακτήρων για εσοχή, με " "τοποθέτηση αγκίστρων K&R:" #. (itstool) path: item/code #: C/c-coding-style.page:107 #, no-wrap msgid "" "\n" "for (i = 0; i < num_elements; i++) {\n" "\tfoo[i] = foo[i] + 42;\n" "\n" "\tif (foo[i] < 35) {\n" "\t\tprintf (\"Foo!\");\n" "\t\tfoo[i]--;\n" "\t} else {\n" "\t\tprintf (\"Bar!\");\n" "\t\tfoo[i]++;\n" "\t}\n" "}" msgstr "" "\n" "for (i = 0; i < num_elements; i++) {\n" "\tfoo[i] = foo[i] + 42;\n" "\n" "\tif (foo[i] < 35) {\n" "\t\tprintf (\"Foo!\");\n" "\t\tfoo[i]--;\n" "\t} else {\n" "\t\tprintf (\"Bar!\");\n" "\t\tfoo[i]++;\n" "\t}\n" "}" #. (itstool) path: item/p #: C/c-coding-style.page:122 msgid "" "GNU style. Each new level is indented by 2 spaces, braces go on a line by " "themselves, and they are indented as well." msgstr "" #. (itstool) path: item/code #: C/c-coding-style.page:128 #, no-wrap msgid "" "\n" "for (i = 0; i < num_elements; i++)\n" " {\n" " foo[i] = foo[i] + 42;\n" "\n" " if (foo[i] < 35)\n" " {\n" " printf (\"Foo!\");\n" " foo[i]--;\n" " }\n" " else\n" " {\n" " printf (\"Bar!\");\n" " foo[i]++;\n" " }\n" " }" msgstr "" "\n" "for (i = 0; i < num_elements; i++)\n" " {\n" " foo[i] = foo[i] + 42;\n" "\n" " if (foo[i] < 35)\n" " {\n" " printf (\"Foo!\");\n" " foo[i]--;\n" " }\n" " else\n" " {\n" " printf (\"Bar!\");\n" " foo[i]++;\n" " }\n" " }" #. (itstool) path: section/p #: C/c-coding-style.page:148 msgid "" "Both styles have their pros and cons. The most important things is to be " "consistent 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." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:157 msgid "" "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: be " "consistent 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." msgstr "" #. (itstool) path: section/title #: C/c-coding-style.page:170 msgid "Tab Characters" msgstr "Χαρακτήρες στηλοθέτη" #. (itstool) path: section/p #: C/c-coding-style.page:172 msgid "" "Do not ever change the size of tabs in your editor; leave them as 8 " "spaces. Changing the size of tabs means that code that you didn’t write " "yourself will be perpetually misaligned." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:178 msgid "" "Instead, set the indentation size 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." msgstr "" #. (itstool) path: section/title #: C/c-coding-style.page:188 #, fuzzy msgid "Braces" msgstr "Ενεργοποίηση ελέγχου αγκίστρων" #. (itstool) path: section/p #: C/c-coding-style.page:190 msgid "Curly braces should not be used for single statement blocks:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:194 #, no-wrap msgid "" "\n" "/* valid */\n" "if (condition)\n" "\tsingle_statement ();\n" "else\n" "\tanother_single_statement (arg1);" msgstr "" "\n" "/* valid */\n" "if (condition)\n" "\tsingle_statement ();\n" "else\n" "\tanother_single_statement (arg1);" #. (itstool) path: section/p #: C/c-coding-style.page:201 msgid "The “no block for single statements” rule has only four exceptions:" msgstr "" #. (itstool) path: item/p #: C/c-coding-style.page:208 msgid "" "In GNU style, if either side of an if-else statement has braces, both sides " "should, to match up indentation:" msgstr "" #. (itstool) path: item/code #: C/c-coding-style.page:213 #, no-wrap msgid "" "\n" "/* valid GNU style */\n" "if (condition)\n" " {\n" " foo ();\n" " bar ();\n" " }\n" "else\n" " {\n" " baz ();\n" " }" msgstr "" "\n" "/* valid GNU style */\n" "if (condition)\n" " {\n" " foo ();\n" " bar ();\n" " }\n" "else\n" " {\n" " baz ();\n" " }" #. (itstool) path: item/code #: C/c-coding-style.page:225 #, no-wrap msgid "" "\n" "/* invalid */\n" "if (condition)\n" " {\n" " foo ();\n" " bar ();\n" " }\n" "else\n" " baz ();" msgstr "" "\n" "/* invalid */\n" "if (condition)\n" " {\n" " foo ();\n" " bar ();\n" " }\n" "else\n" " baz ();" #. (itstool) path: item/p #: C/c-coding-style.page:237 msgid "" "If the single statement covers multiple lines, e.g. for functions with many " "arguments, and it is followed by else or else if:" msgstr "" #. (itstool) path: item/code #: C/c-coding-style.page:243 #, no-wrap msgid "" "\n" "/* valid Linux kernel style */\n" "if (condition) {\n" "\ta_single_statement_with_many_arguments (some_lengthy_argument,\n" "\t\t\t\t\t\tanother_lengthy_argument,\n" "\t\t\t\t\t\tand_another_one,\n" "\t\t\t\t\t\tplus_one);\n" "} else\n" "\tanother_single_statement (arg1, arg2);\n" "\n" "/* valid GNU style */\n" "if (condition)\n" " {\n" " a_single_statement_with_many_arguments (some_lengthy_argument,\n" " another_lengthy_argument,\n" " and_another_one,\n" " plus_one);\n" " }\n" "else\n" " {\n" " another_single_statement (arg1, arg2);\n" " }" msgstr "" "\n" "/* valid Linux kernel style */\n" "if (condition) {\n" "\ta_single_statement_with_many_arguments (some_lengthy_argument,\n" "\t\t\t\t\t\tanother_lengthy_argument,\n" "\t\t\t\t\t\tand_another_one,\n" "\t\t\t\t\t\tplus_one);\n" "} else\n" "\tanother_single_statement (arg1, arg2);\n" "\n" "/* valid GNU style */\n" "if (condition)\n" " {\n" " a_single_statement_with_many_arguments (some_lengthy_argument,\n" " another_lengthy_argument,\n" " and_another_one,\n" " plus_one);\n" " }\n" "else\n" " {\n" " another_single_statement (arg1, arg2);\n" " }" #. (itstool) path: item/p #: C/c-coding-style.page:268 msgid "If the condition is composed of many lines:" msgstr "" #. (itstool) path: item/code #: C/c-coding-style.page:272 #, no-wrap msgid "" "\n" "/* valid Linux kernel style */\n" "if (condition1 ||\n" " (condition2 && condition3) ||\n" " condition4 ||\n" " (condition5 && (condition6 || condition7))) {\n" "\ta_single_statement ();\n" "}\n" "\n" "/* valid GNU style */\n" "if (condition1 ||\n" " (condition2 && condition3) ||\n" " condition4 ||\n" " (condition5 && (condition6 || condition7)))\n" " {\n" " a_single_statement ();\n" " }" msgstr "" "\n" "/* valid Linux kernel style */\n" "if (condition1 ||\n" " (condition2 && condition3) ||\n" " condition4 ||\n" " (condition5 && (condition6 || condition7))) {\n" "\ta_single_statement ();\n" "}\n" "\n" "/* valid GNU style */\n" "if (condition1 ||\n" " (condition2 && condition3) ||\n" " condition4 ||\n" " (condition5 && (condition6 || condition7)))\n" " {\n" " a_single_statement ();\n" " }" #. (itstool) path: item/p #: C/c-coding-style.page:290 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/c-coding-style.page:299 msgid "" "Nested ifs, in which case the block should be placed on the " "outermost if:" msgstr "" #. (itstool) path: item/code #: C/c-coding-style.page:304 #, no-wrap msgid "" "\n" "/* valid Linux kernel style */\n" "if (condition) {\n" "\tif (another_condition)\n" "\t\tsingle_statement ();\n" "\telse\n" "\t\tanother_single_statement ();\n" "}\n" "\n" "/* valid GNU style */\n" "if (condition)\n" " {\n" " if (another_condition)\n" " single_statement ();\n" " else\n" " another_single_statement ();\n" " }" msgstr "" "\n" "/* valid Linux kernel style */\n" "if (condition) {\n" "\tif (another_condition)\n" "\t\tsingle_statement ();\n" "\telse\n" "\t\tanother_single_statement ();\n" "}\n" "\n" "/* valid GNU style */\n" "if (condition)\n" " {\n" " if (another_condition)\n" " single_statement ();\n" " else\n" " another_single_statement ();\n" " }" #. (itstool) path: item/code #: C/c-coding-style.page:322 #, no-wrap msgid "" "\n" "/* invalid */\n" "if (condition)\n" "\tif (another_condition)\n" "\t\tsingle_statement ();\n" "\telse if (yet_another_condition)\n" "\t\tanother_single_statement ();" msgstr "" "\n" "/* invalid */\n" "if (condition)\n" "\tif (another_condition)\n" "\t\tsingle_statement ();\n" "\telse if (yet_another_condition)\n" "\t\tanother_single_statement ();" #. (itstool) path: section/p #: C/c-coding-style.page:332 msgid "" "In general, new blocks should be placed on a new indentation level, like " "this:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:337 #, no-wrap msgid "" "\n" "int retval = 0;\n" "\n" "statement_1 ();\n" "statement_2 ();\n" "\n" "{\n" "\tint var1 = 42;\n" "\tgboolean res = FALSE;\n" "\n" "\tres = statement_3 (var1);\n" "\n" "\tretval = res ? -1 : 1;\n" "}" msgstr "" "\n" "int retval = 0;\n" "\n" "statement_1 ();\n" "statement_2 ();\n" "\n" "{\n" "\tint var1 = 42;\n" "\tgboolean res = FALSE;\n" "\n" "\tres = statement_3 (var1);\n" "\n" "\tretval = res ? -1 : 1;\n" "}" #. (itstool) path: section/p #: C/c-coding-style.page:352 msgid "" "While curly braces for function definitions should rest on a new line they " "should not add an indentation level:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:357 #, no-wrap msgid "" "\n" "/* valid Linux kernel style*/\n" "static void\n" "my_function (int argument)\n" "{\n" "\tdo_my_things ();\n" "}\n" "\n" "/* valid GNU style*/\n" "static void\n" "my_function (int argument)\n" "{\n" " do_my_things ();\n" "}" msgstr "" "\n" "/* valid Linux kernel style*/\n" "static void\n" "my_function (int argument)\n" "{\n" "\tdo_my_things ();\n" "}\n" "\n" "/* valid GNU style*/\n" "static void\n" "my_function (int argument)\n" "{\n" " do_my_things ();\n" "}" #. (itstool) path: section/code #: C/c-coding-style.page:372 #, no-wrap msgid "" "\n" "/* invalid */\n" "static void\n" "my_function (int argument) {\n" "\tdo_my_things ();\n" "}\n" "\n" "/* invalid */\n" "static void\n" "my_function (int argument)\n" " {\n" " do_my_things ();\n" " }" msgstr "" "\n" "/* invalid */\n" "static void\n" "my_function (int argument) {\n" "\tdo_my_things ();\n" "}\n" "\n" "/* invalid */\n" "static void\n" "my_function (int argument)\n" " {\n" " do_my_things ();\n" " }" #. (itstool) path: section/title #: C/c-coding-style.page:388 msgid "Conditions" msgstr "Συνθήκες" #. (itstool) path: section/p #: C/c-coding-style.page:390 msgid "" "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 TRUE macro uses. For example:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:397 #, no-wrap msgid "" "\n" "/* invalid */\n" "if (found == TRUE)\n" "\tdo_foo ();\n" "\n" "/* invalid */\n" "if (found == FALSE)\n" "\tdo_bar ();" msgstr "" "\n" "/* invalid */\n" "if (found == TRUE)\n" "\tdo_foo ();\n" "\n" "/* invalid */\n" "if (found == FALSE)\n" "\tdo_bar ();" #. (itstool) path: section/code #: C/c-coding-style.page:406 #, no-wrap msgid "" "\n" "/* valid */\n" "if (found)\n" "\tdo_foo ();\n" "\n" "/* valid */\n" "if (!found)\n" "\tdo_bar ();" msgstr "" "\n" "/* valid */\n" "if (found)\n" "\tdo_foo ();\n" "\n" "/* valid */\n" "if (!found)\n" "\tdo_bar ();" #. (itstool) path: section/p #: C/c-coding-style.page:415 msgid "" "The C language uses the value 0 for many purposes. As a numeric value, the " "end of a string, a null pointer and the FALSE 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:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:426 #, no-wrap msgid "" "\n" "/* valid */\n" "if (some_pointer == NULL)\n" "\tdo_blah ();\n" "\n" "/* valid */\n" "if (number == 0)\n" "\tdo_foo ();\n" "\n" "/* valid */\n" "if (str != NULL && *str != '\\0')\n" "\tdo_bar ();" msgstr "" "\n" "/* valid */\n" "if (some_pointer == NULL)\n" "\tdo_blah ();\n" "\n" "/* valid */\n" "if (number == 0)\n" "\tdo_foo ();\n" "\n" "/* valid */\n" "if (str != NULL && *str != '\\0')\n" "\tdo_bar ();" #. (itstool) path: section/code #: C/c-coding-style.page:439 #, no-wrap msgid "" "\n" "/* invalid */\n" "if (!some_pointer)\n" "\tdo_blah ();\n" "\n" "/* invalid */\n" "if (!number)\n" "\tdo_foo ();\n" "\n" "/* invalid */\n" "if (str && *str)\n" "\tdo_bar ();" msgstr "" "\n" "/* invalid */\n" "if (!some_pointer)\n" "\tdo_blah ();\n" "\n" "/* invalid */\n" "if (!number)\n" "\tdo_foo ();\n" "\n" "/* invalid */\n" "if (str && *str)\n" "\tdo_bar ();" #. (itstool) path: section/title #: C/c-coding-style.page:454 msgid "Functions" msgstr "Συναρτήσεις" #. (itstool) path: section/p #: C/c-coding-style.page:456 msgid "" "Functions should be declared by placing the returned value on a separate " "line from the function name:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:461 #, no-wrap msgid "" "\n" "void\n" "my_function (void)\n" "{\n" " …\n" "}" msgstr "" "\n" "void\n" "my_function (void)\n" "{\n" " …\n" "}" #. (itstool) path: section/p #: C/c-coding-style.page:468 msgid "" "The argument list must be broken into a new line for each argument, with the " "argument names right aligned, taking into account pointers:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:474 #, no-wrap msgid "" "\n" "void\n" "my_function (some_type_t type,\n" " another_type_t *a_pointer,\n" " double_ptr_t **double_pointer,\n" " final_type_t another_type)\n" "{\n" " …\n" "}" msgstr "" "\n" "void\n" "my_function (some_type_t type,\n" " another_type_t *a_pointer,\n" " double_ptr_t **double_pointer,\n" " final_type_t another_type)\n" "{\n" " …\n" "}" #. (itstool) path: section/p #: C/c-coding-style.page:484 msgid "" "If you use Emacs, you can use M-x align to do this kind of " "alignment automatically. Just put the point and mark around the function’s " "prototype, and invoke that command." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:490 msgid "" "The alignment also holds when invoking a function without breaking the line " "length limit:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:495 #, no-wrap msgid "" "\n" "align_function_arguments (first_argument,\n" " second_argument,\n" " third_argument);" msgstr "" "\n" "align_function_arguments (first_argument,\n" " second_argument,\n" " third_argument);" #. (itstool) path: section/title #: C/c-coding-style.page:502 msgid "Whitespace" msgstr "Κενά διαστήματα" #. (itstool) path: section/p #: C/c-coding-style.page:504 msgid "Always put a space before an opening parenthesis but never after:" msgstr "" "Προσθέστε πάντα ένα διάστημα πριν το άνοιγμα μιας παρένθεσης αλλά ποτέ μετά:" #. (itstool) path: section/code #: C/c-coding-style.page:508 #, no-wrap msgid "" "\n" "/* valid */\n" "if (condition)\n" "\tdo_my_things ();\n" "\n" "/* valid */\n" "switch (condition) {\n" "}" msgstr "" "\n" "/* valid */\n" "if (condition)\n" "\tdo_my_things ();\n" "\n" "/* valid */\n" "switch (condition) {\n" "}" #. (itstool) path: section/code #: C/c-coding-style.page:517 #, no-wrap msgid "" "\n" "/* invalid */\n" "if(condition)\n" "\tdo_my_things();\n" "\n" "/* invalid */\n" "if ( condition )\n" "\tdo_my_things ( );" msgstr "" "\n" "/* invalid */\n" "if(condition)\n" "\tdo_my_things();\n" "\n" "/* invalid */\n" "if ( condition )\n" "\tdo_my_things ( );" #. (itstool) path: section/p #: C/c-coding-style.page:526 msgid "" "When declaring a structure type use newlines to separate logical sections of " "the structure:" msgstr "" "Όταν ορίζετε μια δομή χρησιμοποιήστε νέες γραμμές για να διαχωρίσετε τα " "λογικά κομμάτια της δομής:" #. (itstool) path: section/code #: C/c-coding-style.page:531 #, no-wrap msgid "" "\n" "struct _GtkWrapBoxPrivate\n" "{\n" "\tGtkOrientation orientation;\n" "\tGtkWrapAllocationMode mode;\n" "\n" "\tGtkWrapBoxSpreading horizontal_spreading;\n" "\tGtkWrapBoxSpreading vertical_spreading;\n" "\n" "\tguint16 vertical_spacing;\n" "\tguint16 horizontal_spacing;\n" "\n" "\tguint16 minimum_line_children;\n" "\tguint16 natural_line_children;\n" "\n" "\tGList *children;\n" "};" msgstr "" "\n" "struct _GtkWrapBoxPrivate\n" "{\n" "\tGtkOrientation orientation;\n" "\tGtkWrapAllocationMode mode;\n" "\n" "\tGtkWrapBoxSpreading horizontal_spreading;\n" "\tGtkWrapBoxSpreading vertical_spreading;\n" "\n" "\tguint16 vertical_spacing;\n" "\tguint16 horizontal_spacing;\n" "\n" "\tguint16 minimum_line_children;\n" "\tguint16 natural_line_children;\n" "\n" "\tGList *children;\n" "};" #. (itstool) path: section/p #: C/c-coding-style.page:549 msgid "" "Do not eliminate whitespace and newlines just because something would fit on " "a single line:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:554 #, no-wrap msgid "" "\n" "/* invalid */\n" "if (condition) foo (); else bar ();" msgstr "" "\n" "/* invalid */\n" "if (condition) foo (); else bar ();" #. (itstool) path: section/p #: C/c-coding-style.page:558 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:564 msgid "" "This is a little Emacs function that you can use to clean up lines with " "trailing whitespace:" msgstr "" "Παρακάτω ακολουθεί μια συνάρτηση Emacs με την οποία μπορείτε να καθαρίσετε " "τις γραμμές με κενά διαστήματα στο τέλος αυτής." #. (itstool) path: section/code #: C/c-coding-style.page:569 #, no-wrap msgid "" "\n" "(defun clean-line-ends ()\n" " (interactive)\n" " (if (not buffer-read-only)\n" " (save-excursion\n" "\t(goto-char (point-min))\n" "\t(let ((count 0))\n" "\t (while (re-search-forward \"[ \t]+$\" nil t)\n" "\t (setq count (+ count 1))\n" "\t (replace-match \"\" t t))\n" "\t (message \"Cleaned %d lines\" count)))))" msgstr "" "\n" "(defun clean-line-ends ()\n" " (interactive)\n" " (if (not buffer-read-only)\n" " (save-excursion\n" "\t(goto-char (point-min))\n" "\t(let ((count 0))\n" "\t (while (re-search-forward \"[ \t]+$\" nil t)\n" "\t (setq count (+ count 1))\n" "\t (replace-match \"\" t t))\n" "\t (message \"Cleaned %d lines\" count)))))" #. (itstool) path: section/title #: C/c-coding-style.page:583 msgid "The switch Statement" msgstr "Η συνθήκη switch" #. (itstool) path: section/p #: C/c-coding-style.page:585 msgid "" "A switch should open a block on a new indentation level, and " "each case should start on the same indentation level as the " "curly braces, with the case block on a new indentation level:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:592 #, no-wrap msgid "" "\n" "/* valid Linux kernel style */\n" "switch (condition) {\n" "case FOO:\n" "\tdo_foo ();\n" "\tbreak;\n" "\n" "case BAR:\n" "\tdo_bar ();\n" "\tbreak;\n" "}\n" "\n" "/* valid GNU style */\n" "switch (condition)\n" " {\n" " case FOO:\n" " do_foo ();\n" " break;\n" "\n" " case BAR:\n" " do_bar ();\n" " break;\n" " }" msgstr "" "\n" "/* valid Linux kernel style */\n" "switch (condition) {\n" "case FOO:\n" "\tdo_foo ();\n" "\tbreak;\n" "\n" "case BAR:\n" "\tdo_bar ();\n" "\tbreak;\n" "}\n" "\n" "/* valid GNU style */\n" "switch (condition)\n" " {\n" " case FOO:\n" " do_foo ();\n" " break;\n" "\n" " case BAR:\n" " do_bar ();\n" " break;\n" " }" #. (itstool) path: section/code #: C/c-coding-style.page:616 #, no-wrap msgid "" "\n" "/* invalid */\n" "switch (condition) {\n" " case FOO: do_foo (); break;\n" " case BAR: do_bar (); break;\n" "}\n" "\n" "/* invalid */\n" "switch (condition)\n" " {\n" " case FOO: do_foo ();\n" " break;\n" " case BAR: do_bar ();\n" " break;\n" " }\n" "\n" "/* invalid */\n" "switch (condition)\n" " {\n" " case FOO:\n" " do_foo ();\n" " break;\n" " case BAR:\n" " do_bar ();\n" " break;\n" " }" msgstr "" "\n" "/* invalid */\n" "switch (condition) {\n" " case FOO: do_foo (); break;\n" " case BAR: do_bar (); break;\n" "}\n" "\n" "/* invalid */\n" "switch (condition)\n" " {\n" " case FOO: do_foo ();\n" " break;\n" " case BAR: do_bar ();\n" " break;\n" " }\n" "\n" "/* invalid */\n" "switch (condition)\n" " {\n" " case FOO:\n" " do_foo ();\n" " break;\n" " case BAR:\n" " do_bar ();\n" " break;\n" " }" #. (itstool) path: section/p #: C/c-coding-style.page:643 msgid "" "It is preferable, though not mandatory, to separate the various cases with a " "newline:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:648 #, no-wrap msgid "" "\n" "switch (condition) {\n" "case FOO:\n" "\tdo_foo ();\n" "\tbreak;\n" "\n" "case BAR:\n" "\tdo_bar ();\n" "\tbreak;\n" "\n" "default:\n" "\tdo_default ();\n" "}" msgstr "" "\n" "switch (condition) {\n" "case FOO:\n" "\tdo_foo ();\n" "\tbreak;\n" "\n" "case BAR:\n" "\tdo_bar ();\n" "\tbreak;\n" "\n" "default:\n" "\tdo_default ();\n" "}" #. (itstool) path: section/p #: C/c-coding-style.page:662 msgid "" "The break statement for the default case is not " "mandatory." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:667 msgid "" "If switching over an enumerated type, a case statement must " "exist for every member of the enumerated type. For members you do not want " "to handle, alias their case statements to default:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:674 #, no-wrap msgid "" "\n" "switch (enumerated_condition) {\n" "case HANDLED_1:\n" "\tdo_foo ();\n" "\tbreak;\n" "\n" "case HANDLED_2:\n" "\tdo_bar ();\n" "\tbreak;\n" "\n" "case IGNORED_1:\n" "case IGNORED_2:\n" "default:\n" "\tdo_default ();\n" "}" msgstr "" "\n" "switch (enumerated_condition) {\n" "case HANDLED_1:\n" "\tdo_foo ();\n" "\tbreak;\n" "\n" "case HANDLED_2:\n" "\tdo_bar ();\n" "\tbreak;\n" "\n" "case IGNORED_1:\n" "case IGNORED_2:\n" "default:\n" "\tdo_default ();\n" "}" #. (itstool) path: section/p #: C/c-coding-style.page:690 msgid "" "If most members of the enumerated type should not be handled, consider using " "an if statement instead of a switch." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:695 msgid "" "If a case block needs to declare new variables, the same rules " "as the inner blocks apply (see above); the break statement " "should be placed outside of the inner block:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:701 #, no-wrap msgid "" "\n" "/* valid GNU style */\n" "switch (condition)\n" " {\n" " case FOO:\n" " {\n" " int foo;\n" "\n" " foo = do_foo ();\n" " }\n" " break;\n" "\n" " …\n" " }" msgstr "" "\n" "/* valid GNU style */\n" "switch (condition)\n" " {\n" " case FOO:\n" " {\n" " int foo;\n" "\n" " foo = do_foo ();\n" " }\n" " break;\n" "\n" " …\n" " }" #. (itstool) path: section/title #: C/c-coding-style.page:718 msgid "Header Files" msgstr "Κεφαλίδες" #. (itstool) path: section/p #: C/c-coding-style.page:720 msgid "" "The only major rule for headers is that the function definitions should be " "vertically aligned in three columns:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:725 #, no-wrap msgid "" "\n" "return_type function_name (type argument,\n" " type argument,\n" " type argument);" msgstr "" "\n" "return_type function_name (type argument,\n" " type argument,\n" " type argument);" #. (itstool) path: section/p #: C/c-coding-style.page:730 msgid "" "The maximum width of each column is given by the longest element in the " "column:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:735 #, no-wrap msgid "" "\n" "void gtk_type_set_property (GtkType *type,\n" " const gchar *value,\n" " GError **error);\n" "const gchar *gtk_type_get_property (GtkType *type);" msgstr "" "\n" "void gtk_type_set_property (GtkType *type,\n" " const gchar *value,\n" " GError **error);\n" "const gchar *gtk_type_get_property (GtkType *type);" #. (itstool) path: section/p #: C/c-coding-style.page:741 msgid "It is also possible to align the columns to the next tab:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:745 #, no-wrap msgid "" "\n" "void gtk_type_set_prop (GtkType *type,\n" " gfloat value);\n" "gfloat gtk_type_get_prop (GtkType *type);\n" "gint gtk_type_update_foobar (GtkType *type);" msgstr "" "\n" "void gtk_type_set_prop (GtkType *type,\n" " gfloat value);\n" "gfloat gtk_type_get_prop (GtkType *type);\n" "gint gtk_type_update_foobar (GtkType *type);" #. (itstool) path: section/p #: C/c-coding-style.page:751 msgid "" "As before, you can use M-x align in Emacs to do this " "automatically." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:756 msgid "" "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:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:766 #, no-wrap msgid "" "\n" "#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)\n" "#error \"Only <gtk/gtk.h> can be included directly.\"\n" "#endif" msgstr "" "\n" "#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)\n" "#error \"Only <gtk/gtk.h> can be included directly.\"\n" "#endif" #. (itstool) path: section/p #: C/c-coding-style.page:771 msgid "" "For libraries, all headers should have inclusion guards (for internal usage) " "and C++ guards. These provide the extern \"C\" magic that C++ " "requires to include plain C headers:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:777 #, no-wrap msgid "" "\n" "#ifndef MYLIB_FOO_H_\n" "#define MYLIB_FOO_H_\n" "\n" "#include <gtk/gtk.h>\n" "\n" "G_BEGIN_DECLS\n" "\n" "…\n" "\n" "G_END_DECLS\n" "\n" "#endif /* MYLIB_FOO_H_ */" msgstr "" "\n" "#ifndef MYLIB_FOO_H_\n" "#define MYLIB_FOO_H_\n" "\n" "#include <gtk/gtk.h>\n" "\n" "G_BEGIN_DECLS\n" "\n" "…\n" "\n" "G_END_DECLS\n" "\n" "#endif /* MYLIB_FOO_H_ */" #. (itstool) path: section/title #: C/c-coding-style.page:793 msgid "GObject Classes" msgstr "Κλάσεις GObject" #. (itstool) path: section/p #: C/c-coding-style.page:795 msgid "" "GObject class definitions and implementations require some additional coding " "style notices, and should always be correctly namespaced." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:801 msgid "Typedef declarations should be placed at the beginning of the file:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:805 #, no-wrap msgid "" "\n" "typedef struct _GtkBoxedStruct GtkBoxedStruct;\n" "typedef struct _GtkMoreBoxedStruct GtkMoreBoxedStruct;" msgstr "" "\n" "typedef struct _GtkBoxedStruct GtkBoxedStruct;\n" "typedef struct _GtkMoreBoxedStruct GtkMoreBoxedStruct;" #. (itstool) path: section/p #: C/c-coding-style.page:809 #, fuzzy msgid "This includes enumeration types:" msgstr "Απαρίθμηση" #. (itstool) path: section/code #: C/c-coding-style.page:813 #, no-wrap msgid "" "\n" "typedef enum\n" "{\n" " GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT,\n" " GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH\n" "} GtkSizeRequestMode;" msgstr "" "\n" "typedef enum\n" "{\n" " GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT,\n" " GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH\n" "} GtkSizeRequestMode;" #. (itstool) path: section/p #: C/c-coding-style.page:820 msgid "And callback types:" msgstr "Και τύπους επανάκλησης:" #. (itstool) path: section/code #: C/c-coding-style.page:824 #, no-wrap msgid "" "\n" "typedef void (* GtkCallback) (GtkWidget *widget,\n" " gpointer user_data);" msgstr "" "\n" "typedef void (* GtkCallback) (GtkWidget *widget,\n" " gpointer user_data);" #. (itstool) path: section/p #: C/c-coding-style.page:828 msgid "" "Instance structures should be declared using G_DECLARE_FINAL_TYPE or G_DECLARE_DERIVABLE_TYPE:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:834 #, no-wrap msgid "" "\n" "#define GTK_TYPE_FOO (gtk_foo_get_type ())\n" "G_DECLARE_FINAL_TYPE (GtkFoo, gtk_foo, GTK, FOO, GtkWidget)" msgstr "" "\n" "#define GTK_TYPE_FOO (gtk_foo_get_type ())\n" "G_DECLARE_FINAL_TYPE (GtkFoo, gtk_foo, GTK, FOO, GtkWidget)" #. (itstool) path: section/p #: C/c-coding-style.page:838 msgid "" "For final types, private data can be stored in the object struct, which " "should be defined in the C file:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:843 #, no-wrap msgid "" "\n" "struct _GtkFoo\n" "{\n" " GObject parent_instance;\n" "\n" " guint private_data;\n" " gpointer more_private_data;\n" "};" msgstr "" "\n" "struct _GtkFoo\n" "{\n" " GObject parent_instance;\n" "\n" " guint private_data;\n" " gpointer more_private_data;\n" "};" #. (itstool) path: section/p #: C/c-coding-style.page:852 msgid "" "For derivable types, private data must be stored in a private struct in the " "C file, configured using G_DEFINE_TYPE_WITH_PRIVATE() and " "accessed using a _get_instance_private() function:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:858 #, no-wrap msgid "" "\n" "#define GTK_TYPE_FOO gtk_foo_get_type ()\n" "G_DECLARE_DERIVABLE_TYPE (GtkFoo, gtk_foo, GTK, FOO, GtkWidget)\n" "\n" "struct _GtkFooClass\n" "{\n" " GtkWidgetClass parent_class;\n" "\n" " void (* handle_frob) (GtkFrobber *frobber,\n" " guint n_frobs);\n" "\n" " gpointer padding[12];\n" "};" msgstr "" "\n" "#define GTK_TYPE_FOO gtk_foo_get_type ()\n" "G_DECLARE_DERIVABLE_TYPE (GtkFoo, gtk_foo, GTK, FOO, GtkWidget)\n" "\n" "struct _GtkFooClass\n" "{\n" " GtkWidgetClass parent_class;\n" "\n" " void (* handle_frob) (GtkFrobber *frobber,\n" " guint n_frobs);\n" "\n" " gpointer padding[12];\n" "};" #. (itstool) path: section/p #: C/c-coding-style.page:872 msgid "" "Always use the G_DEFINE_TYPE(), " "G_DEFINE_TYPE_WITH_PRIVATE(), and " "G_DEFINE_TYPE_WITH_CODE() macros, or their abstract variants " "G_DEFINE_ABSTRACT_TYPE(), " "G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(), and " "G_DEFINE_ABSTRACT_TYPE_WITH_CODE(); also, use the similar " "macros for defining interfaces and boxed types." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:882 msgid "Interface types should always have the dummy typedef for cast purposes:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:887 #, no-wrap msgid "" "\n" "typedef struct _GtkFooable GtkFooable;" msgstr "" "\n" "typedef struct _GtkFooable GtkFooable;" #. (itstool) path: section/p #: C/c-coding-style.page:890 msgid "" "The interface structure should have ‘Interface’ postfixed to the dummy " "typedef:" msgstr "" #. (itstool) path: section/code #: C/c-coding-style.page:895 #, no-wrap msgid "" "\n" "typedef struct _GtkFooableInterface GtkFooableInterface;" msgstr "" "\n" "typedef struct _GtkFooableInterface GtkFooableInterface;" #. (itstool) path: section/p #: C/c-coding-style.page:898 msgid "Interfaces must have the following macros:" msgstr "" #. (itstool) path: td/p #: C/c-coding-style.page:905 msgid "Macro" msgstr "Μακροεντολή" #. (itstool) path: td/p #: C/c-coding-style.page:906 #, fuzzy msgid "Expands to" msgstr "αναπτύσσει τη γραμμή στο ETree περιλαμβάνοντας το κελί" #. (itstool) path: td/p #: C/c-coding-style.page:911 msgid "GTK_TYPE_iface_name" msgstr "GTK_TYPE_iface_name" #. (itstool) path: td/p #: C/c-coding-style.page:912 msgid "iface_name_get_type" msgstr "iface_name_get_type" #. (itstool) path: td/p #: C/c-coding-style.page:915 msgid "GTK_iface_name" msgstr "GTK_iface_name" #. (itstool) path: td/p #: C/c-coding-style.page:916 msgid "G_TYPE_CHECK_INSTANCE_CAST" msgstr "G_TYPE_CHECK_INSTANCE_CAST" #. (itstool) path: td/p #: C/c-coding-style.page:919 msgid "GTK_IS_iface_name" msgstr "GTK_IS_iface_name" #. (itstool) path: td/p #: C/c-coding-style.page:920 msgid "G_TYPE_CHECK_INSTANCE_TYPE" msgstr "G_TYPE_CHECK_INSTANCE_TYPE" #. (itstool) path: td/p #: C/c-coding-style.page:923 msgid "GTK_iface_name_GET_IFACE" msgstr "GTK_iface_name_GET_IFACE" #. (itstool) path: td/p #: C/c-coding-style.page:924 msgid "G_TYPE_INSTANCE_GET_INTERFACE" msgstr "G_TYPE_INSTANCE_GET_INTERFACE" #. (itstool) path: section/title #: C/c-coding-style.page:932 #, fuzzy msgid "Memory Allocation" msgstr "" "Η Massif έχει πολύ λίγες επιλογές και για τα περισσότερα " "προγράμματα δεν τις χρειάζεστε. Εντούτοις για της εφαρμογές του GNOME, όπου " "η κατανομή μνήμης μπορεί να θαφτεί βαθιά στο glib ή στο GTK, ο αριθμός " "επιπέδων κάτω από την στοίβα κλήσεων που η Massif κατεβαίνει θα πρέπει να " "αυξηθεί. Αυτό είναι γίνεται χρησιμοποιώντας την παράμετρο --depth. Εξ " "ορισμού αυτό είναι ίσο με 3· αυξάνοντας το σε 5 εγγυάται ότι η στοίβα " "κλήσεων θα φθάσει στον κώδικά σας. Ένα ή δύο περισσότερα επίπεδα μπορούν " "επίσης να είναι επιθυμητά και να παρέχουν στον κώδικά σας κάποιο πλαίσιο " "εφαρμογής. Δεδομένου ότι το επίπεδο λεπτομέρειας γίνεται γρήγορα συντριπτικό " "είναι καλύτερο να αρχίσει με μικρότερη παράμετρο βάθους και να το αυξήστε " "μόνο όταν γίνεται προφανές ότι αυτό δεν είναι ικανοποιητικό." #. (itstool) path: section/p #: C/c-coding-style.page:934 msgid "When dynamically allocating data on the heap use g_new()." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:938 msgid "" "Public structure types should always be returned after being zero-ed, either " "explicitly for each member, or by using g_new0()." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:944 msgid "See for more details." msgstr "" "Για περισσότερες λεπτομέρειες δείτε ." #. (itstool) path: section/title #: C/c-coding-style.page:950 msgid "Macros" msgstr "Μακροεντολές" #. (itstool) path: section/p #: C/c-coding-style.page:952 msgid "" "Try to avoid private macros unless strictly necessary. Remember to " "#undef them at the end of a block or a series of functions " "needing them." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:958 msgid "Inline functions are usually preferable to private macros." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:962 msgid "Public macros should not be used unless they evaluate to a constant." msgstr "" #. (itstool) path: section/title #: C/c-coding-style.page:969 msgid "Public API" msgstr "Δημόσιο API" #. (itstool) path: section/p #: C/c-coding-style.page:971 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/c-coding-style.page:980 msgid "Private API" msgstr "Ιδιωτικό API" #. (itstool) path: section/p #: C/c-coding-style.page:982 msgid "" "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, _mylib_internal_foo()." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:988 msgid "Underscore-prefixed functions are never exported." msgstr "" #. (itstool) path: section/p #: C/c-coding-style.page:992 msgid "" "Non-exported functions that are only needed in one source file should be " "declared static." msgstr "" #. (itstool) path: p/link #: C/cc-by-sa-3-0.xml:4 msgid "Creative Commons Attribution-Share Alike 3.0 United States License" msgstr "" #. (itstool) path: license/p #: C/cc-by-sa-3-0.xml:3 msgid "This work is licensed under a <_:link-1/>." msgstr "" #. (itstool) path: license/p #: C/cc-by-sa-3-0.xml:6 msgid "" "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." msgstr "" #. (itstool) path: info/desc #: C/databases.page:18 msgid "Simple persistent object stores" msgstr "" #. (itstool) path: page/title #: C/databases.page:21 msgid "Databases" msgstr "Βάσεις δεδομένων" #. (itstool) path: item/p #: C/databases.page:27 msgid "" "Use databases for appropriate use cases: not configuration data (use " "GSettings). ()" msgstr "" #. (itstool) path: item/p #: C/databases.page:31 msgid "" "Choose between GOM and GVDB based on whether indexing is required. ()" msgstr "" #. (itstool) path: item/p #: C/databases.page:35 msgid "" "Consider your vacuuming policy before committing to using GOM. ()" msgstr "" #. (itstool) path: item/p #: C/databases.page:39 msgid "" "Avoid SQL injection vulnerabilities by using prepared statements. ()" msgstr "" #. (itstool) path: section/title #: C/databases.page:47 msgid "When to Use Databases" msgstr "Πότε να χρησιμοποιήσετε βάσεις δεδομένων" #. (itstool) path: section/p #: C/databases.page:49 msgid "" "Configuration data should be stored in GSettings. 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." msgstr "" #. (itstool) path: section/p #: C/databases.page:60 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/databases.page:69 msgid "" "GOM should be used if you need advanced features, especially indexing. GVDB " "should be used otherwise." msgstr "" #. (itstool) path: section/p #: C/databases.page:74 msgid "" "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 this article on vacuuming for more information; " "please consider it before choosing to use GOM." msgstr "" #. (itstool) path: section/p #: C/databases.page:86 msgid "" "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 user settings." msgstr "" #. (itstool) path: section/title #: C/databases.page:97 msgid "Using GOM" msgstr "Χρήση του GOM" #. (itstool) path: section/p #: C/databases.page:99 msgid "" "Providing a GOM tutorial is beyond the scope of this document, but a reference manual is available." msgstr "" #. (itstool) path: section/title #: C/databases.page:113 #, fuzzy msgid "SQL Injection" msgstr "" "Οι μεταβλητές (μερικές φορές αναφερόμενες ως αντικαταστάτες) είναι " "περιοχές στον κώδικα SQL που αντικαθιστούντε από πραγματικές τιμές όταν ο " "κώδικας SQL εκτελείτε. Τα οφέλη είναι ο ταχύτερος χρόνος εκτέλεσης (Αφού ο " "κώδικας SQL αναλύετε μόνο μία φορά) και η προστασία ενάντια στα κενά " "ασφαλείας του SQL." #. (itstool) path: section/p #: C/databases.page:115 msgid "" "GOM does allow access to the lower level SQLite query APIs. When using them, " "queries must be constructed using SQLite’s prepared statement " "and value " "binding API, rather than by constructing SQL strings then passing " "them to SQLite to parse. Constructing strings makes SQL injection vulnerabilities very " "likely, which can give attackers access to arbitrary user data from the " "database." msgstr "" #. (itstool) path: section/title #: C/databases.page:131 msgid "Using GVDB" msgstr "Χρήση του GVDB" #. (itstool) path: section/p #: C/databases.page:133 msgid "" "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 GVDB " "git and copy it into your project. It is licenced under LGPLv2.1+." msgstr "" #. (itstool) path: section/p #: C/databases.page:141 msgid "A full GVDB tutorial is beyond the scope of this document." msgstr "" #. (itstool) path: info/desc #: C/documentation.page:26 msgid "Adding documentation to libraries and APIs" msgstr "" #. (itstool) path: page/title #. (itstool) path: section/title #: C/documentation.page:29 C/memory-management.page:473 msgid "Documentation" msgstr "Τεκμηρίωση" #. (itstool) path: item/p #: C/documentation.page:35 msgid "" "Use gtk-doc with up-to-date settings for API documentation. ()" msgstr "" #. (itstool) path: item/p #: C/documentation.page:39 msgid "" "Use XML entities for including external symbols into the documentation. " "()" msgstr "" #. (itstool) path: item/p #: C/documentation.page:43 msgid "" "Use a consistent, standard, table of contents for all API documentation to " "maintain familiarity. ()" msgstr "" #. (itstool) path: item/p #: C/documentation.page:47 msgid "" "Use gdbus-codegen to generate D-Bus API documentation to include " "in the gtk-doc build. ()" msgstr "" #. (itstool) path: item/p #: C/documentation.page:51 msgid "" "Add introspection annotations to all API documentation. ()" msgstr "" #. (itstool) path: item/p #: C/documentation.page:55 msgid "" "Add Since lines to all API documentation. ()" msgstr "" #. (itstool) path: item/p #: C/documentation.page:59 msgid "Enable gtk-doc tests. ()" msgstr "" #. (itstool) path: section/title #: C/documentation.page:66 msgid "gtk-doc" msgstr "gtk-doc" #. (itstool) path: section/p #: C/documentation.page:68 msgid "" "The preferred documentation system for GNOME libraries is gtk-doc, which extracts inline " "comments from the code to let you build a DocBook document and collection of HTML pages. These can then be " "read in Devhelp. A " "lot of GNOME’s infrastructure is built to handle with documentation written " "using gtk-doc." msgstr "" #. (itstool) path: section/title #: C/documentation.page:81 msgid "Build System" msgstr "Σύστημα δόμησης" #. (itstool) path: section/p #: C/documentation.page:83 msgid "" "To integrate gtk-doc into a project’s build system, follow the " "instructions in the gtk-doc manual. Note that while the " "sections.txt 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 in version control." msgstr "" #. (itstool) path: section/p #: C/documentation.page:94 msgid "" "gtk-doc’s no-tmpl flavour should be used, and XML mode should " "be used instead of SGML. (tmpl mode and SGML are both outdated and slower " "than XML.)" msgstr "" #. (itstool) path: section/p #: C/documentation.page:106 msgid "" "If the package version is needed to be substituted into the documentation, " "create a file named docs/version.xml.in, containing:" msgstr "" #. (itstool) path: section/code #: C/documentation.page:110 #, no-wrap msgid "@PACKAGE_VERSION@" msgstr "@PACKAGE_VERSION@" #. (itstool) path: section/p #: C/documentation.page:111 msgid "" "Add it to AC_CONFIG_FILES in configure.ac, then " "include it into the main documentation file (*-docs.xml) using: " "<!ENTITY version SYSTEM \"version.xml\"> in the " "DOCTYPE at the top of the document. The package version can " "then be used inline as &version;." msgstr "" #. (itstool) path: section/title #: C/documentation.page:121 msgid "Standard Layout" msgstr "Τυπική διάταξη" #. (itstool) path: section/p #: C/documentation.page:123 msgid "" "Using a standard layout for the table of contents, sections, appendices, " "etc. means the same project-name-docs.xml 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." msgstr "" #. (itstool) path: section/p #: C/documentation.page:131 #, fuzzy msgid "The following layout is suggested:" msgstr "Παρακαλώ εισάγετε τις ακόλουθες πληροφορίες διάταξης." #. (itstool) path: listing/title #: C/documentation.page:135 msgid "project-name-docs.xml" msgstr "project-name-docs.xml" #. (itstool) path: listing/desc #: C/documentation.page:136 msgid "A template top-level gtk-doc file for a project" msgstr "" #. (itstool) path: section/title #: C/documentation.page:142 #, fuzzy msgid "Licensing" msgstr "" "Διάταξη πληκτρολογίου \"%s\"\n" "Πνευματικά δικαιώματα © X.Org Foundation και συντελεστές " "XKeyboardConfig\n" "Για πληροφορίες για την άδεια διάθεσης, δείτε τα μεταδεδομένα του πακέτου" #. (itstool) path: section/p #: C/documentation.page:150 msgid "" "It is important to make the license used for API references clear, " "especially if they contain code examples which could be copied around." msgstr "" #. (itstool) path: section/p #: C/documentation.page:155 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/documentation.page:161 msgid "" "As shown in the Standard Layout you " "should include a license.xml in the top-level gtk-doc DocBook " "file which gives the full text of your documentation license." msgstr "" #. (itstool) path: section/title #: C/documentation.page:169 msgid "Public APIs" msgstr "Δημόσια API" #. (itstool) path: section/p #: C/documentation.page:171 msgid "" "All public APIs must have gtk-doc comments. For functions, these should be " "placed in the source file, directly above the function." msgstr "" #. (itstool) path: section/code #: C/documentation.page:176 #, no-wrap msgid "" "/**\n" " * gtk_get_flow:\n" " * @widget: a #GtkWidget\n" " *\n" " * Gets the flow of a widget.\n" " *\n" " * Note that flows may be laminar or turbulent...\n" " *\n" " * Returns: (transfer none): the flow of @widget\n" " */\n" "GtkFlow *\n" "gtk_get_flow (GtkWidget *widget)\n" "{\n" "\n" " ...\n" "\n" "}" msgstr "" "/**\n" " * gtk_get_flow:\n" " * @widget: a #GtkWidget\n" " *\n" " * Gets the flow of a widget.\n" " *\n" " * Note that flows may be laminar or turbulent...\n" " *\n" " * Returns: (transfer none): the flow of @widget\n" " */\n" "GtkFlow *\n" "gtk_get_flow (GtkWidget *widget)\n" "{\n" "\n" " ...\n" "\n" "}" #. (itstool) path: section/p #: C/documentation.page:194 msgid "" "Documentation comments for macros, function types, class structs, etc. " "should be placed next to the definitions, typically in header files." msgstr "" #. (itstool) path: section/p #: C/documentation.page:200 msgid "" "Section introductions should be placed in the source file they describe, " "after the license header:" msgstr "" #. (itstool) path: section/code #: C/documentation.page:205 #, no-wrap msgid "" "/**\n" " * SECTION:gtksizerequest\n" " * @Short_Description: Height-for-width geometry management\n" " * @Title: GtkSizeRequest\n" " *\n" " * The GtkSizeRequest interface is GTK+'s height-for-width (and\n" " * width-for-height) geometry management system.\n" " * ...\n" " */" msgstr "" "/**\n" " * SECTION:gtksizerequest\n" " * @Short_Description: Height-for-width geometry management\n" " * @Title: GtkSizeRequest\n" " *\n" " * The GtkSizeRequest interface is GTK+'s height-for-width (and\n" " * width-for-height) geometry management system.\n" " * ...\n" " */" #. (itstool) path: section/p #: C/documentation.page:215 msgid "" "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 modulename-" "sections.txt file." msgstr "" #. (itstool) path: section/p #: C/documentation.page:221 msgid "" "To properly document a new class, it needs to be given its own section in " "modulename-sections.txt, needs to be included in your toplevel " "modulename-docs.sgml, and the get_type() function " "for your class needs to be listed in your modulename.types." msgstr "" #. (itstool) path: section/title #: C/documentation.page:231 #, fuzzy msgid "Introspection Annotations" msgstr "" "\n" " <!-- ενεργοποιήστε το όταν χρησιμοποιείτε σχόλια αυτοελέγχου gobject\n" " <xi:include href=\"xml/annotation-glossary.xml\"><xi:fallback /" "></xi:include>\n" " --> \n" #. (itstool) path: section/p #: C/documentation.page:233 msgid "" "Each gtk-doc comment should have appropriate GObject introspection " "annotations. These are useful for two reasons:" msgstr "" #. (itstool) path: item/p #: C/documentation.page:240 msgid "" "They add important information about parameter types, nullability and memory " "management to the C API documentation generated by gtk-doc." msgstr "" #. (itstool) path: item/p #: C/documentation.page:244 msgid "" "They allow public APIs to be automatically bound in other languages, such as " "Python or JavaScript." msgstr "" #. (itstool) path: section/p #: C/documentation.page:250 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/documentation.page:258 msgid "" "In gtk-doc comments, annotations should be preferred over human-readable " "equivalents. For example, when documenting a function parameter which may be " "NULL, use the (nullable) annotation rather than " "some text:" msgstr "" #. (itstool) path: section/code #: C/documentation.page:264 #, no-wrap msgid "" "/**\n" " * my_function:\n" " * @parameter: (nullable): some parameter which affects something\n" " *\n" " * Body of the function documentation.\n" " */" msgstr "" "/**\n" " * my_function:\n" " * @parameter: (nullable): some parameter which affects something\n" " *\n" " * Body of the function documentation.\n" " */" #. (itstool) path: section/p #: C/documentation.page:271 msgid "Instead of:" msgstr "Αντί για:" #. (itstool) path: section/code #: C/documentation.page:274 #, no-wrap msgid "" "/**\n" " * my_bad_function:\n" " * @parameter: some parameter which affects something, or %NULL to ignore\n" " *\n" " * Bad body of the function documentation.\n" " */" msgstr "" "/**\n" " * my_bad_function:\n" " * @parameter: some parameter which affects something, or %NULL to ignore\n" " *\n" " * Bad body of the function documentation.\n" " */" #. (itstool) path: section/p #: C/documentation.page:281 msgid "" "For more information on introspection, see the introspection guidelines." msgstr "" #. (itstool) path: section/title #: C/documentation.page:288 #, fuzzy msgid "Symbol Versioning" msgstr "Εκδόσεις" #. (itstool) path: section/p #: C/documentation.page:290 msgid "" "Whenever a symbol is added to the public API, it should have a documentation " "comment added. This comment should always contain a Since line " "with the package version number of the release which will first contain the " "new API. This should be the number currently in configure.ac if " "post-release version incrementing is being used." msgstr "" #. (itstool) path: section/p #. (itstool) path: example/p #: C/documentation.page:300 C/memory-management.page:494 C/threading.page:79 msgid "For example:" msgstr "Για παράδειγμα:" #. (itstool) path: section/code #: C/documentation.page:303 #, no-wrap msgid "" "/**\n" " * my_function:\n" " * @param: some parameter\n" " *\n" " * Body of the function documentation.\n" " *\n" " * Since: 0.5.0\n" " */" msgstr "" "/**\n" " * my_function:\n" " * @param: some parameter\n" " *\n" " * Body of the function documentation.\n" " *\n" " * Since: 0.5.0\n" " */" #. (itstool) path: section/p #: C/documentation.page:312 msgid "" "gtk-doc uses this information to generate indexes of the APIs added in each " "release. These should be added to the main *-docs.xml as an " "appendix:" msgstr "" #. (itstool) path: section/code #: C/documentation.page:317 #, no-wrap msgid "" "<part>\n" "\t<title>Appendices</title>\n" "\t<index id=\"api-index-full\">\n" "\t\t<title>API Index</title>\n" "\t\t<xi:include href=\"xml/api-index-full.xml\"><xi:fallback/></xi:include>\n" "\t</index>\n" "\t<index id=\"api-index-deprecated\">\n" "\t\t<title>Index of deprecated symbols</title>\n" "\t\t<xi:include href=\"xml/api-index-deprecated.xml\"><xi:fallback/></xi:include>\n" "\t</index>\n" "\t<index role=\"0.1.0\">\n" "\t\t<title>Index of new symbols in 0.1.0</title>\n" "\t\t<xi:include href=\"xml/api-index-0.1.0.xml\"><xi:fallback/></xi:include>\n" "\t</index>\n" "\t<!-- More versions here. -->\n" "\t<xi:include href=\"xml/annotation-glossary.xml\"><xi:fallback /></xi:include>\n" "</part>" msgstr "" "<part>\n" "\t<title>Appendices</title>\n" "\t<index id=\"api-index-full\">\n" "\t\t<title>API Index</title>\n" "\t\t<xi:include href=\"xml/api-index-full.xml\"><xi:fallback/></xi:include>\n" "\t</index>\n" "\t<index id=\"api-index-deprecated\">\n" "\t\t<title>Index of deprecated symbols</title>\n" "\t\t<xi:include href=\"xml/api-index-deprecated.xml\"><xi:fallback/></xi:include>\n" "\t</index>\n" "\t<index role=\"0.1.0\">\n" "\t\t<title>Index of new symbols in 0.1.0</title>\n" "\t\t<xi:include href=\"xml/api-index-0.1.0.xml\"><xi:fallback/></xi:include>\n" "\t</index>\n" "\t<!-- More versions here. -->\n" "\t<xi:include href=\"xml/annotation-glossary.xml\"><xi:fallback /></xi:include>\n" "</part>" #. (itstool) path: section/title #: C/documentation.page:337 msgid "D-Bus APIs" msgstr "D-Bus API" #. (itstool) path: section/p #: C/documentation.page:339 msgid "" "D-Bus interface descriptions contain documentation comments, and these can " "be extracted from the XML using gdbus-codegen, and turned into " "DocBook files to be included by gtk-doc." msgstr "" #. (itstool) path: section/p #: C/documentation.page:352 msgid "" "The DocBook files can be included in the main *-docs.xml file " "using:" msgstr "" #. (itstool) path: section/code #: C/documentation.page:356 #, no-wrap msgid "" "<chapter>\n" " <title>C Interfaces</title>\n" " <partintro>\n" " <para>C wrappers for the D-Bus interfaces.</para>\n" " </partintro>\n" "\n" " <xi:include href=\"xml/SomeDBusService.xml\"/>\n" " <xi:include href=\"xml/SomeOtherService.xml\"/>\n" "</chapter>" msgstr "" "<chapter>\n" " <title>C Interfaces</title>\n" " <partintro>\n" " <para>C wrappers for the D-Bus interfaces.</para>\n" " </partintro>\n" "\n" " <xi:include href=\"xml/SomeDBusService.xml\"/>\n" " <xi:include href=\"xml/SomeOtherService.xml\"/>\n" "</chapter>" #. (itstool) path: section/p #: C/documentation.page:366 msgid "" "The generated XML files must be included in the content_files " "variable in your gtk-doc Makefile.am, otherwise the build will " "fail. (This is to fix situations where the builddir does not " "equal the srcdir.)" msgstr "" #. (itstool) path: section/title #: C/documentation.page:375 #, fuzzy msgid "Keeping Documentation Up to Date" msgstr "Δημιουργία του σκελετού τεκμηρίωσης" #. (itstool) path: section/p #: C/documentation.page:377 msgid "" "gtk-doc comes with support for checking the documentation with some basic " "tests. These check that all version indexes are included in the main *-" "docs.xml file and that all symbols are documented, amongst other " "things." msgstr "" #. (itstool) path: section/p #: C/documentation.page:384 msgid "" "These tests should always be enabled, by adding the following to your gtk-" "doc Makefile.am:" msgstr "" #. (itstool) path: section/code #: C/documentation.page:388 #, no-wrap msgid "TESTS = $(GTKDOC_CHECK)" msgstr "TESTS = $(GTKDOC_CHECK)" #. (itstool) path: section/p #: C/documentation.page:390 msgid "They will then be run as part of make check." msgstr "" #. (itstool) path: info/desc #: C/file-system.page:18 #, fuzzy msgid "Accessing the file system" msgstr "Σύστημα αρχείων" #. (itstool) path: page/title #: C/file-system.page:21 #, fuzzy msgid "File System Access" msgstr "Πρόσβαση αρχείων:" #. (itstool) path: synopsis/p #: C/file-system.page:26 msgid "" "There are a few anti-patterns to consider when accessing the file system. " "This article assumes knowledge of the standard GFile, GInputStream and GOutputStream APIs." msgstr "" #. (itstool) path: item/p #: C/file-system.page:37 msgid "" "Use asynchronous I/O for file access. ()" msgstr "" #. (itstool) path: item/p #: C/file-system.page:41 msgid "" "Always use appropriate functions to construct file names and paths. ()" msgstr "" #. (itstool) path: item/p #: C/file-system.page:45 msgid "" "Validate file paths are in the expected directories before using them. " "()" msgstr "" #. (itstool) path: item/p #: C/file-system.page:49 msgid "" "Use mandatory access control profiles to enforce constraints on file access. " "()" msgstr "" #. (itstool) path: section/title #: C/file-system.page:58 #, fuzzy msgid "Asynchronous I/O" msgstr "_Πάροχοι εισόδου/εξόδου" #. (itstool) path: section/p #: C/file-system.page:60 msgid "" "Almost all I/O should be performed asynchronously. That is, without blocking " "the GLib main context. This can be achieved by always using " "the *_async() and *_finish() variants of each I/O " "function." msgstr "" #. (itstool) path: example/p #: C/file-system.page:70 msgid "" "For example, g_input_stream_read_async() rather than g_input_stream_read()." msgstr "" #. (itstool) path: section/p #: C/file-system.page:78 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/file-system.page:84 msgid "" "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 /proc. For such " "reads, the low level functions g_open(), read() " "and g_close() should be used rather than GIO." msgstr "" #. (itstool) path: section/p #: C/file-system.page:93 msgid "" "Files in the user’s home directory do not count as local, as they " "could be on a networked file system." msgstr "" #. (itstool) path: section/p #: C/file-system.page:98 msgid "" "Note that the alternative – running synchronous I/O in a separate thread – " "is highly discouraged; see the threading guidelines for more information." msgstr "" #. (itstool) path: section/title #: C/file-system.page:107 #, fuzzy msgid "File Path Construction" msgstr "Κατασκευές" #. (itstool) path: section/p #: C/file-system.page:109 msgid "" "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.)" msgstr "" #. (itstool) path: example/p #: C/file-system.page:120 msgid "" "For example, file paths should be built using g_build_filename() rather than g_strconcat()." msgstr "" #. (itstool) path: section/p #: C/file-system.page:128 msgid "" "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)." msgstr "" #. (itstool) path: example/p #: C/file-system.page:135 msgid "" "As another example, paths should be disassembled using g_path_get_basename() and g_path_get_dirname() " "rather than g_strrstr() and other " "manual searching functions." msgstr "" #. (itstool) path: section/title #: C/file-system.page:148 #, fuzzy msgid "Path Validation and Sandboxing" msgstr "Εγκυρότητα" #. (itstool) path: section/p #: C/file-system.page:150 msgid "" "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 ~/ plus some user input, if the user " "inputs ../../etc/passwd, 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." msgstr "" #. (itstool) path: section/p #: C/file-system.page:161 msgid "" "This can be avoided by validating constructed paths before using them, using " "g_file_resolve_relative_path() " "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 ~/Downloads, using g_file_has_parent()." msgstr "" #. (itstool) path: section/p #: C/file-system.page:172 msgid "" "As a second line of defence, all projects which access the file system " "should consider providing a mandatory access control profile, using a system " "such as AppArmor or SELinux, which limits the directories " "and files they can read from and write to." msgstr "" #. (itstool) path: info/desc #: C/gerror.page:18 #, fuzzy msgid "Runtime error handling and reporting" msgstr "Παρουσιάστηκε σφάλμα κατά την αναφορά προβλήματος." #. (itstool) path: page/title #: C/gerror.page:21 msgid "GError" msgstr "GError" #. (itstool) path: section/title #: C/gerror.page:24 msgid "GError Usage" msgstr "Χρήση GError" #. (itstool) path: section/p #: C/gerror.page:26 msgid "" "GError is the standard error reporting mechanism " "for GLib-using code, and can be thought of as a C implementation of an exception." msgstr "" #. (itstool) path: section/p #: C/gerror.page:33 msgid "" "Any kind of runtime failure (anything which is not a programmer error) must be handled by including a " "GError** 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." msgstr "" #. (itstool) path: section/p #: C/gerror.page:42 msgid "" "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, introspecting an API will " "automatically detect all GError parameters so that they can be converted to " "exceptions in other languages." msgstr "" #. (itstool) path: section/p #: C/gerror.page:50 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/gerror.page:58 msgid "" "Any function call which can take a GError**, should " "take such a parameter, and the returned GError should be handled " "appropriately. There are very few situations where ignoring a potential " "error by passing NULL to a GError** parameter is " "acceptable." msgstr "" #. (itstool) path: section/p #: C/gerror.page:66 msgid "" "The GLib API documentation contains a full tutorial for using GError." msgstr "" #. (itstool) path: info/desc #: C/glist.page:18 msgid "Linked lists and container types" msgstr "" #. (itstool) path: page/title #: C/glist.page:21 msgid "GList" msgstr "GList" #. (itstool) path: section/title #: C/glist.page:24 msgid "GList Usage" msgstr "Χρήση GList" #. (itstool) path: section/p #: C/glist.page:26 msgid "" "GLib provides several container types for sets of data: GList, GSList, GPtrArray and GArray." msgstr "" #. (itstool) path: section/p #: C/glist.page:34 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/glist.page:45 msgid "" "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 " "g_list_nth() or g_list_nth_data() is almost certainly wrong. For " "example, iteration over a GList should be implemented using the linking " "pointers, rather than a incrementing index:" msgstr "" #. (itstool) path: section/code #: C/glist.page:54 #, no-wrap msgid "" "GList *some_list, *l;\n" "\n" "for (l = some_list; l != NULL; l = l->next)\n" " {\n" " gpointer element_data = l->data;\n" "\n" " /* Do something with @element_data. */\n" " }" msgstr "" "GList *some_list, *l;\n" "\n" "for (l = some_list; l != NULL; l = l->next)\n" " {\n" " gpointer element_data = l->data;\n" "\n" " /* Do something with @element_data. */\n" " }" #. (itstool) path: section/p #: C/glist.page:63 msgid "" "Using an incrementing index instead results in a quadratic decrease in " "performance (O(N^2) rather than O(N)):" msgstr "" #. (itstool) path: section/code #: C/glist.page:67 #, no-wrap msgid "" "GList *some_list;\n" "guint i;\n" "\n" "/* This code is inefficient and should not be used in production. */\n" "for (i = 0; i < g_list_length (some_list); i++)\n" " {\n" " gpointer element_data = g_list_nth_data (some_list, i);\n" "\n" " /* Do something with @element_data. */\n" " }" msgstr "" "GList *some_list;\n" "guint i;\n" "\n" "/* This code is inefficient and should not be used in production. */\n" "for (i = 0; i < g_list_length (some_list); i++)\n" " {\n" " gpointer element_data = g_list_nth_data (some_list, i);\n" "\n" " /* Do something with @element_data. */\n" " }" #. (itstool) path: section/p #: C/glist.page:78 msgid "" "The performance penalty comes from g_list_length() and " "g_list_nth_data() which both traverse the list (O(N)) " "to perform their operations." msgstr "" #. (itstool) path: section/p #: C/glist.page:84 msgid "" "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:" msgstr "" #. (itstool) path: section/code #: C/glist.page:89 #, no-wrap msgid "" "GPtrArray *some_array;\n" "guint i;\n" "\n" "for (i = 0; i < some_array->len; i++)\n" " {\n" " gpointer element_data = some_array->pdata[i];\n" "\n" " /* Do something with @element_data. */\n" " }" msgstr "" "GPtrArray *some_array;\n" "guint i;\n" "\n" "for (i = 0; i < some_array->len; i++)\n" " {\n" " gpointer element_data = some_array->pdata[i];\n" "\n" " /* Do something with @element_data. */\n" " }" #. (itstool) path: credit/name #: C/index.page:13 C/writing-good-code.page:15 msgid "Miguel de Icaza" msgstr "Miguel de Icaza" #. (itstool) path: credit/name #: C/index.page:17 C/writing-good-code.page:19 msgid "Morten Welinder" msgstr "Morten Welinder" #. (itstool) path: credit/name #: C/index.page:26 msgid "GNOME Foundation" msgstr "Ίδρυμα GNOME" #. (itstool) path: credit/page #: C/index.page:27 msgid "http://foundation.gnome.org/" msgstr "http://foundation.gnome.org/" #. (itstool) path: info/desc #. (itstool) path: page/title #: C/index.page:32 C/index.page:37 #, fuzzy msgid "GNOME Programming Guidelines" msgstr "Οδηγίες ανθρώπινης διεπαφής του GNOME" #. (itstool) path: info/title #: C/index.page:34 #, fuzzy msgctxt "link:trail" msgid "Programming Guidelines" msgstr "Προγραμματισμός" #. (itstool) path: page/p #: C/index.page:39 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/index.page:50 msgid "This guide has a two-fold purpose:" msgstr "" #. (itstool) path: item/p #: C/index.page:56 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/index.page:65 msgid "" "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." msgstr "" #. (itstool) path: info/title #: C/index.page:75 msgctxt "link:trail" msgid "General Guidelines" msgstr "Γενικές οδηγίες" #. (itstool) path: section/title #: C/index.page:77 msgid "General Guidelines" msgstr "Γενικές οδηγίες" #. (itstool) path: info/title #: C/index.page:83 #, fuzzy msgctxt "link:trail" msgid "Maintainer Guidelines" msgstr "_Συντηρητής" #. (itstool) path: section/title #: C/index.page:85 #, fuzzy msgid "Maintainer Guidelines" msgstr "_Συντηρητής" #. (itstool) path: info/title #: C/index.page:91 #, fuzzy msgctxt "link:trail" msgid "Specific How-Tos" msgstr "Τύπος υπηρεσίας (TOS):" #. (itstool) path: section/title #: C/index.page:93 #, fuzzy msgid "Specific How-Tos" msgstr "Τύπος υπηρεσίας (TOS):" #. (itstool) path: info/title #: C/index.page:99 msgctxt "link:trail" msgid "References" msgstr "Αναφορές" #. (itstool) path: section/title #: C/index.page:101 msgid "References" msgstr "Αναφορές" #. (itstool) path: info/desc #: C/introspection.page:17 msgid "GObject Introspection support in library code" msgstr "" #. (itstool) path: page/title #: C/introspection.page:20 #, fuzzy msgid "Introspection" msgstr "Ενδοσκόπηση" #. (itstool) path: synopsis/p #: C/introspection.page:25 msgid "" " GObject " "introspection (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 introspect or wrap 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." msgstr "" #. (itstool) path: synopsis/p #: C/introspection.page:37 msgid "" "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 add " "introspection annotations to documentation comments in program code, " "as they clarify the documentation." msgstr "" #. (itstool) path: item/p #: C/introspection.page:46 msgid "" "Enable introspection for all libraries. ()" msgstr "" #. (itstool) path: item/p #: C/introspection.page:50 msgid "" "Pay attention to warnings from g-ir-scanner and " "introspectable=\"0\" attributes in GIR files. ()" msgstr "" #. (itstool) path: item/p #: C/introspection.page:55 msgid "" "Add introspection annotations to all documentation comments. ()" msgstr "" #. (itstool) path: item/p #: C/introspection.page:59 msgid "" "Design APIs to be introspectable from the start. ()" msgstr "" #. (itstool) path: section/title #: C/introspection.page:67 #, fuzzy msgid "Using Introspection" msgstr "Ενδοσκόπηση" #. (itstool) path: section/p #: C/introspection.page:69 msgid "" "The first step for using introspection is to add it to the build system, " "following the instructions here, following method 1. This should be done early " "in the life of a project, as introspectability affects API design." msgstr "" #. (itstool) path: section/p #: C/introspection.page:77 msgid "" "This should result in a .gir and .typelib file " "being generated for the project. The .gir 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 introspectable=\"0\" will not be exposed to language " "bindings as they are missing annotations or are otherwise not representable " "in the GIR file." msgstr "" #. (itstool) path: section/p #: C/introspection.page:88 msgid "" "The next step is to add annotations to the documentation comments for every piece of public " "API. If a particular piece of API should not be exposed in the GIR " "file, use the (skip) annotation. Documentation on the available " "annotations is here." msgstr "" #. (itstool) path: section/p #: C/introspection.page:98 msgid "" "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 ). 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." msgstr "" #. (itstool) path: section/p #: C/introspection.page:108 msgid "" "Annotations do not have to be added exhaustively: GIR has a set of default " "annotations which it applies based on various conventions (see ). For example, a const gchar* parameter does " "not need an explicit (transfer none) annotation, because the " "const modifier implies this already. Learning the defaults for " "annotations is a matter of practice." msgstr "" #. (itstool) path: section/title #: C/introspection.page:119 msgid "API Design" msgstr "Σχεδιασμός API" #. (itstool) path: section/p #: C/introspection.page:121 msgid "" "In order to be introspectable without too many annotations, APIs must follow " "certain conventions, such as the standard GObject naming conventions, and the conventions for bindable APIs. 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." msgstr "" #. (itstool) path: section/p #: C/introspection.page:134 msgid "" "For example, GIR expects that if a function can fail, it will have a " "GError** 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 " "GError* is returned directly, or is not the final function " "parameter, for example." msgstr "" #. (itstool) path: section/p #: C/introspection.page:143 msgid "" "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 va_list)." msgstr "" #. (itstool) path: section/p #: C/introspection.page:151 msgid "" "g-ir-scanner emits warnings when it encounters code it does not " "understand. By passing --warn-error as well as --warn-all in INTROSPECTION_SCANNER_ARGS in Makefile.am, " "compilation will fail when unintrospectable APIs are encountered. This will " "ensure all new APIs are introspectable, and is highly recommended." msgstr "" #. (itstool) path: info/desc #: C/logging.page:18 msgid "Logging debug and information output from libraries and programs" msgstr "" #. (itstool) path: page/title #: C/logging.page:23 msgid "Logging" msgstr "Καταγραφή" #. (itstool) path: synopsis/p #: C/logging.page:28 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/logging.page:40 msgid "" "Use the GLib logging framework instead of logging directly to stderr and " "stdout. ()" msgstr "" #. (itstool) path: item/p #: C/logging.page:44 msgid "" "If systemd can be a dependency of the project, consider logging directly to " "the journal. ()" msgstr "" #. (itstool) path: item/p #: C/logging.page:48 msgid "" "Do not implement log rotation and deletion; leave that to system services. " "()" msgstr "" #. (itstool) path: section/title #: C/logging.page:56 #, fuzzy msgid "GLib Logging Framework" msgstr "Σύνδεση..." #. (itstool) path: section/p #: C/logging.page:58 msgid "" "GLib provides a logging framework based around the g_log() function, with convenience wrappers g_debug(), g_message(), g_warning() and g_error(). The GLib logging framework has a few " "useful features:" msgstr "" #. (itstool) path: item/p #: C/logging.page:72 msgid "" "Programmatic redirection of log messages using g_log_set_handler()." msgstr "" #. (itstool) path: item/p #: C/logging.page:76 msgid "Multiple logging domains, which can be processed separately." msgstr "" #. (itstool) path: item/p #: C/logging.page:79 msgid "" "Multiple log levels, which can be processed separately. For example, this " "allows debug messages to be turned on and off at runtime." msgstr "" #. (itstool) path: item/p #: C/logging.page:83 msgid "Support for automatically aborting a program on ‘fatal’ messages." msgstr "" #. (itstool) path: section/p #: C/logging.page:88 msgid "" "These should be used in preference to functions like printf(), " "g_print() and g_printerr(), 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." msgstr "" #. (itstool) path: section/p #: C/logging.page:99 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/logging.page:105 msgid "" "To use the GLib logging framework, define G_LOG_DOMAIN for the project so it’s unique from all " "other projects. Call g_debug(\"Message\") to log a debug " "message." msgstr "" #. (itstool) path: section/p #: C/logging.page:112 msgid "" "If the default GLib log handlers are not sufficient, for example if log " "messages need to be in a custom format or journald integration is needed, set up a log handler with the " "following code:" msgstr "" #. (itstool) path: section/code #: C/logging.page:118 #, no-wrap msgid "" "\n" "static const gchar *\n" "log_level_to_string (GLogLevelFlags level)\n" "{\n" " switch (level)\n" " {\n" " case G_LOG_LEVEL_ERROR: return \"ERROR\";\n" " case G_LOG_LEVEL_CRITICAL: return \"CRITICAL\";\n" " case G_LOG_LEVEL_WARNING: return \"WARNING\";\n" " case G_LOG_LEVEL_MESSAGE: return \"MESSAGE\";\n" " case G_LOG_LEVEL_INFO: return \"INFO\";\n" " case G_LOG_LEVEL_DEBUG: return \"DEBUG\";\n" " default: return \"UNKNOWN\";\n" " }\n" "}\n" "\n" "static void\n" "log_handler_cb (const gchar *log_domain,\n" " GLogLevelFlags log_level,\n" " const gchar *message,\n" " gpointer user_data)\n" "{\n" " const gchar *log_level_str;\n" "\n" " /* Ignore debug messages if disabled. */\n" " if (!debug_enabled && (log_level & G_LOG_LEVEL_DEBUG))\n" " {\n" " return;\n" " }\n" "\n" " log_level_str = log_level_to_string (log_level & G_LOG_LEVEL_MASK);\n" "\n" " /* Use g_printerr() for warnings and g_print() otherwise. */\n" " if (flags <= G_LOG_LEVEL_WARNING)\n" " {\n" " g_printerr (\"%s: %s: %s\\n\", log_domain, log_level_str, message);\n" " }\n" " else\n" " {\n" " g_print (\"%s: %s: %s\\n\", log_domain, log_level_str, message);\n" " }\n" "}\n" "\n" "g_log_set_handler (\"log-domain\",\n" " G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,\n" " log_handler_cb, NULL);" msgstr "" "\n" "static const gchar *\n" "log_level_to_string (GLogLevelFlags level)\n" "{\n" " switch (level)\n" " {\n" " case G_LOG_LEVEL_ERROR: return \"ERROR\";\n" " case G_LOG_LEVEL_CRITICAL: return \"CRITICAL\";\n" " case G_LOG_LEVEL_WARNING: return \"WARNING\";\n" " case G_LOG_LEVEL_MESSAGE: return \"MESSAGE\";\n" " case G_LOG_LEVEL_INFO: return \"INFO\";\n" " case G_LOG_LEVEL_DEBUG: return \"DEBUG\";\n" " default: return \"UNKNOWN\";\n" " }\n" "}\n" "\n" "static void\n" "log_handler_cb (const gchar *log_domain,\n" " GLogLevelFlags log_level,\n" " const gchar *message,\n" " gpointer user_data)\n" "{\n" " const gchar *log_level_str;\n" "\n" " /* Ignore debug messages if disabled. */\n" " if (!debug_enabled && (log_level & G_LOG_LEVEL_DEBUG))\n" " {\n" " return;\n" " }\n" "\n" " log_level_str = log_level_to_string (log_level & G_LOG_LEVEL_MASK);\n" "\n" " /* Use g_printerr() for warnings and g_print() otherwise. */\n" " if (flags <= G_LOG_LEVEL_WARNING)\n" " {\n" " g_printerr (\"%s: %s: %s\\n\", log_domain, log_level_str, message);\n" " }\n" " else\n" " {\n" " g_print (\"%s: %s: %s\\n\", log_domain, log_level_str, message);\n" " }\n" "}\n" "\n" "g_log_set_handler (\"log-domain\",\n" " G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,\n" " log_handler_cb, NULL);" #. (itstool) path: section/title #: C/logging.page:166 msgid "Exceptions" msgstr "Εξαιρέσεις" #. (itstool) path: item/p #: C/logging.page:169 msgid "" "Do not use g_message() in normal code to print output. Printing " "output should be done at the top level of an application, using " "g_print(), and should be quite rare; i.e. only done in command " "line applications." msgstr "" #. (itstool) path: item/p #: C/logging.page:175 msgid "" "Do not use g_warning() in library code. Use GErrors instead." msgstr "" #. (itstool) path: item/p #: C/logging.page:179 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/logging.page:189 msgid "journald Integration" msgstr "Ενσωμάτωση στο journald" #. (itstool) path: section/p #: C/logging.page:191 msgid "" "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 systemd-journal as a dependency " "to a project, the project’s log handling function could be extended to use " "sd_journal_print() and sd_journal_send() " "instead of g_print() and g_printerr()." msgstr "" #. (itstool) path: section/p #: C/logging.page:202 msgid "" "For more information, see this article on logging to the journal." msgstr "" #. (itstool) path: section/title #: C/logging.page:210 #, fuzzy msgid "Log Rotation" msgstr "Περιστροφή:" #. (itstool) path: section/p #: C/logging.page:212 msgid "" "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 logrotate or systemd-journald." msgstr "" #. (itstool) path: credit/years #: C/main-contexts.page:13 msgid "2014–2015" msgstr "2014–2015" #. (itstool) path: info/desc #: C/main-contexts.page:18 msgid "" "GLib main contexts, invoking functions in other threads, and the event loop" msgstr "" #. (itstool) path: page/title #: C/main-contexts.page:24 #, fuzzy msgid "GLib Main Contexts" msgstr "Όλα τα περιεχόμενα" #. (itstool) path: item/p #: C/main-contexts.page:30 msgid "" "Use g_main_context_invoke_full() to invoke functions in other threads, assuming every thread has " "a thread default main context which runs throughout the lifetime of that " "thread ()" msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:37 msgid "" "Use GTask to run a function in the background without " "caring about the specific thread used ()" msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:43 msgid "" "Liberally use assertions to check which context executes each function, and " "add these assertions when first writing the code ()" msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:48 msgid "" "Explicitly document contexts a function is expected to be called in, a " "callback will be invoked in, or a signal will be emitted in ()" msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:53 msgid "" "Beware of g_idle_add() and similar functions which implicitly " "use the global-default main context ()" msgstr "" #. (itstool) path: section/title #: C/main-contexts.page:62 msgid "What is GMainContext?" msgstr "Τι είναι GMainContext;" #. (itstool) path: section/p #: C/main-contexts.page:64 msgid "" "GMainContext is a generalized " "implementation of an event loop, 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 GMainContext requires understanding " "poll() and polled I/O." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:74 msgid "" "A GMainContext has a set of GSources 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:" msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:84 msgid "" "Prepare sources, determining if any of them are ready to dispatch " "immediately." msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:88 msgid "" "Poll the sources, blocking the current thread until an event is received for " "one of the sources." msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:92 msgid "Check which of the sources received an event (several could have)." msgstr "" #. (itstool) path: item/p #: C/main-contexts.page:95 msgid "Dispatch callbacks from those sources." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:100 msgid "" "This is explained very well in the GLib documentation." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:108 msgid "" "At its core, GMainContext is just a poll() loop, " "with the preparation, check and dispatch stages of the loop corresponding to " "the normal preamble and postamble in a typical poll() loop " "implementation, such as listing 1 from this article. Typically, some complexity is needed in non-" "trivial poll()-using applications to track the lists of FDs " "which are being polled. Additionally, GMainContext adds a lot " "of useful functionality which vanilla poll() doesn’t support. " "Most importantly, it adds thread safety." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:121 msgid "" "GMainContext is completely thread safe, meaning that a " "GSource can be created in one thread and attached to a " "GMainContext running in another thread. (See also: .) A typical use for this might be to allow worker threads to " "control which sockets are being listened to by a GMainContext " "in a central I/O thread. Each GMainContext is ‘acquired’ by a " "thread for each iteration it’s put through. Other threads cannot iterate a " "GMainContext without acquiring it, which guarantees that a " "GSource and its FDs will only be polled by one thread at once " "(since each GSource is attached to at most one " "GMainContext). A GMainContext can be swapped " "between threads across iterations, but this is expensive." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:137 msgid "" "GMainContext is used instead of poll() mostly for " "convenience, as it transparently handles dynamically managing the array of " "FDs to pass to poll(), especially when operating over multiple " "threads. This is done by encapsulating FDs in GSources, which " "decide whether those FDs should be passed to the poll() call on " "each ‘prepare’ stage of the main context iteration." msgstr "" #. (itstool) path: section/title #: C/main-contexts.page:149 msgid "What is GMainLoop?" msgstr "Τι είναι GMainLoop;" #. (itstool) path: section/p #: C/main-contexts.page:151 msgid "" "GMainLoop is essentially the " "following few lines of code, once reference counting and locking have been " "removed (from g_main_loop_run()):" msgstr "" #. (itstool) path: section/code #: C/main-contexts.page:157 #, no-wrap msgid "" "loop->is_running = TRUE;\n" "while (loop->is_running)\n" " {\n" " g_main_context_iteration (context, TRUE);\n" " }" msgstr "" "loop->is_running = TRUE;\n" "while (loop->is_running)\n" " {\n" " g_main_context_iteration (context, TRUE);\n" " }" #. (itstool) path: section/p #: C/main-contexts.page:163 msgid "" "Plus a fourth line in g_main_loop_quit() which sets loop->is_running = FALSE and which " "will cause the loop to terminate once the current main context iteration " "ends." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:170 msgid "" "Hence, GMainLoop is a convenient, thread-safe way of running a " "GMainContext to process events until a desired exit condition " "is met, at which point g_main_loop_quit() 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." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:178 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/main-contexts.page:186 #, fuzzy msgid "Default Contexts" msgstr "Όλα τα περιεχόμενα" #. (itstool) path: section/p #: C/main-contexts.page:188 msgid "" "One of the important features of GMainContext 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 " "g_main_context_default()) is run by GTK+ when gtk_main() is called. It’s also used for timeouts (g_timeout_add()) " "and idle callbacks (g_idle_add()) — these won’t be dispatched " "unless the default context is running! (See: .)" msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:200 msgid "" "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 " "g_main_context_push_thread_default() 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 GMainContext pointer " "around everywhere." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:214 msgid "" "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 GTask: when " "a new GTask 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 g_task_run_in_thread()." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:227 msgid "" "For example, the code below will run a GTask 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 interesting_context." msgstr "" #. (itstool) path: example/code #: C/main-contexts.page:234 #, no-wrap msgid "" "\n" "typedef struct {\n" " GMainLoop *main_loop;\n" " guint n_remaining;\n" "} WriteData;\n" "\n" "/* This is always called in the same thread as thread_cb() because\n" " * it’s always dispatched in the @worker_context. */\n" "static void\n" "write_cb (GObject *source_object,\n" " GAsyncResult *result,\n" " gpointer user_data)\n" "{\n" " WriteData *data = user_data;\n" " GOutputStream *stream = G_OUTPUT_STREAM (source_object);\n" " GError *error = NULL;\n" " gssize len;\n" "\n" " /* Finish the write. */\n" " len = g_output_stream_write_finish (stream, result, &error);\n" " if (error != NULL)\n" " {\n" " g_error (\"Error: %s\", error->message);\n" " g_error_free (error);\n" " }\n" "\n" " /* Check whether all parallel operations have finished. */\n" " write_data->n_remaining--;\n" "\n" " if (write_data->n_remaining == 0)\n" " {\n" " g_main_loop_quit (write_data->main_loop);\n" " }\n" "}\n" "\n" "/* This is called in a new thread. */\n" "static void\n" "thread_cb (GTask *task,\n" " gpointer source_object,\n" " gpointer task_data,\n" " GCancellable *cancellable)\n" "{\n" " /* These streams come from somewhere else in the program: */\n" " GOutputStream *output_stream1, *output_stream;\n" " GMainContext *worker_context;\n" " GBytes *data;\n" " const guint8 *buf;\n" " gsize len;\n" "\n" " /* Set up a worker context for the writes’ callbacks. */\n" " worker_context = g_main_context_new ();\n" " g_main_context_push_thread_default (worker_context);\n" "\n" " /* Set up the writes. */\n" " write_data.n_remaining = 2;\n" " write_data.main_loop = g_main_loop_new (worker_context, FALSE);\n" "\n" " data = g_task_get_task_data (task);\n" " buf = g_bytes_get_data (data, &len);\n" "\n" " g_output_stream_write_async (output_stream1, buf, len,\n" " G_PRIORITY_DEFAULT, NULL, write_cb,\n" " &write_data);\n" " g_output_stream_write_async (output_stream2, buf, len,\n" " G_PRIORITY_DEFAULT, NULL, write_cb,\n" " &write_data);\n" "\n" " /* Run the main loop until both writes have finished. */\n" " g_main_loop_run (write_data.main_loop);\n" " g_task_return_boolean (task, TRUE); /* ignore errors */\n" "\n" " g_main_loop_unref (write_data.main_loop);\n" "\n" " g_main_context_pop_thread_default (worker_context);\n" " g_main_context_unref (worker_context);\n" "}\n" "\n" "/* This can be called from any thread. Its @callback will always be\n" " * dispatched in the thread which currently owns\n" " * @interesting_context. */\n" "void\n" "parallel_writes_async (GBytes *data,\n" " GMainContext *interesting_context,\n" " GCancellable *cancellable,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data)\n" "{\n" " GTask *task;\n" "\n" " g_main_context_push_thread_default (interesting_context);\n" "\n" " task = g_task_new (NULL, cancellable, callback, user_data);\n" " g_task_set_task_data (task, data,\n" " (GDestroyNotify) g_bytes_unref);\n" " g_task_run_in_thread (task, thread_cb);\n" " g_object_unref (task);\n" "\n" " g_main_context_pop_thread_default (interesting_context);\n" "}" msgstr "" "\n" "typedef struct {\n" " GMainLoop *main_loop;\n" " guint n_remaining;\n" "} WriteData;\n" "\n" "/* This is always called in the same thread as thread_cb() because\n" " * it’s always dispatched in the @worker_context. */\n" "static void\n" "write_cb (GObject *source_object,\n" " GAsyncResult *result,\n" " gpointer user_data)\n" "{\n" " WriteData *data = user_data;\n" " GOutputStream *stream = G_OUTPUT_STREAM (source_object);\n" " GError *error = NULL;\n" " gssize len;\n" "\n" " /* Finish the write. */\n" " len = g_output_stream_write_finish (stream, result, &error);\n" " if (error != NULL)\n" " {\n" " g_error (\"Error: %s\", error->message);\n" " g_error_free (error);\n" " }\n" "\n" " /* Check whether all parallel operations have finished. */\n" " write_data->n_remaining--;\n" "\n" " if (write_data->n_remaining == 0)\n" " {\n" " g_main_loop_quit (write_data->main_loop);\n" " }\n" "}\n" "\n" "/* This is called in a new thread. */\n" "static void\n" "thread_cb (GTask *task,\n" " gpointer source_object,\n" " gpointer task_data,\n" " GCancellable *cancellable)\n" "{\n" " /* These streams come from somewhere else in the program: */\n" " GOutputStream *output_stream1, *output_stream;\n" " GMainContext *worker_context;\n" " GBytes *data;\n" " const guint8 *buf;\n" " gsize len;\n" "\n" " /* Set up a worker context for the writes’ callbacks. */\n" " worker_context = g_main_context_new ();\n" " g_main_context_push_thread_default (worker_context);\n" "\n" " /* Set up the writes. */\n" " write_data.n_remaining = 2;\n" " write_data.main_loop = g_main_loop_new (worker_context, FALSE);\n" "\n" " data = g_task_get_task_data (task);\n" " buf = g_bytes_get_data (data, &len);\n" "\n" " g_output_stream_write_async (output_stream1, buf, len,\n" " G_PRIORITY_DEFAULT, NULL, write_cb,\n" " &write_data);\n" " g_output_stream_write_async (output_stream2, buf, len,\n" " G_PRIORITY_DEFAULT, NULL, write_cb,\n" " &write_data);\n" "\n" " /* Run the main loop until both writes have finished. */\n" " g_main_loop_run (write_data.main_loop);\n" " g_task_return_boolean (task, TRUE); /* ignore errors */\n" "\n" " g_main_loop_unref (write_data.main_loop);\n" "\n" " g_main_context_pop_thread_default (worker_context);\n" " g_main_context_unref (worker_context);\n" "}\n" "\n" "/* This can be called from any thread. Its @callback will always be\n" " * dispatched in the thread which currently owns\n" " * @interesting_context. */\n" "void\n" "parallel_writes_async (GBytes *data,\n" " GMainContext *interesting_context,\n" " GCancellable *cancellable,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data)\n" "{\n" " GTask *task;\n" "\n" " g_main_context_push_thread_default (interesting_context);\n" "\n" " task = g_task_new (NULL, cancellable, callback, user_data);\n" " g_task_set_task_data (task, data,\n" " (GDestroyNotify) g_bytes_unref);\n" " g_task_run_in_thread (task, thread_cb);\n" " g_object_unref (task);\n" "\n" " g_main_context_pop_thread_default (interesting_context);\n" "}" #. (itstool) path: section/title #: C/main-contexts.page:336 msgid "Implicit Use of the Global-Default Main Context" msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:338 msgid "" "Several functions implicitly add sources to the global-default main context. " "They should not be used in threaded code. Instead, use " "g_source_attach() with the GSource created by the " "replacement function from the table below." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:345 msgid "" "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." msgstr "" #. (itstool) path: td/p #: C/main-contexts.page:356 #, fuzzy msgid "Do not use" msgstr "Να χρησιμοποιείται το Wintab API [προεπιλογή]" #. (itstool) path: td/p #: C/main-contexts.page:357 #, fuzzy msgid "Use instead" msgstr "Ορισμός ετικέτας για να χρησιμοποιηθεί αντί για όνομα αρχείου" #. (itstool) path: td/p #: C/main-contexts.page:362 msgid "g_timeout_add()" msgstr "g_timeout_add()" #. (itstool) path: td/p #: C/main-contexts.page:363 msgid "g_timeout_source_new()" msgstr "g_timeout_source_new()" #. (itstool) path: td/p #: C/main-contexts.page:366 msgid "g_idle_add()" msgstr "g_idle_add()" #. (itstool) path: td/p #: C/main-contexts.page:367 msgid "g_idle_source_new()" msgstr "g_idle_source_new()" #. (itstool) path: td/p #: C/main-contexts.page:370 msgid "g_child_watch_add()" msgstr "g_child_watch_add()" #. (itstool) path: td/p #: C/main-contexts.page:371 msgid "g_child_watch_source_new()" msgstr "g_child_watch_source_new()" #. (itstool) path: example/p #: C/main-contexts.page:377 msgid "" "So to delay some computation in a worker thread, use the following code:" msgstr "" #. (itstool) path: example/code #: C/main-contexts.page:381 #, no-wrap msgid "" "\n" "static guint\n" "schedule_computation (guint delay_seconds)\n" "{\n" " GSource *source = NULL;\n" " GMainContext *context;\n" " guint id;\n" "\n" " /* Get the calling context. */\n" " context = g_main_context_get_thread_default ();\n" "\n" " source = g_timeout_source_new_seconds (delay_seconds);\n" " g_source_set_callback (source, do_computation, NULL, NULL);\n" " id = g_source_attach (source, context);\n" " g_source_unref (source);\n" "\n" " /* The ID can be used with the same @context to\n" " * cancel the scheduled computation if needed. */\n" " return id;\n" "}\n" "\n" "static void\n" "do_computation (gpointer user_data)\n" "{\n" " /* … */\n" "}" msgstr "" "\n" "static guint\n" "schedule_computation (guint delay_seconds)\n" "{\n" " GSource *source = NULL;\n" " GMainContext *context;\n" " guint id;\n" "\n" " /* Get the calling context. */\n" " context = g_main_context_get_thread_default ();\n" "\n" " source = g_timeout_source_new_seconds (delay_seconds);\n" " g_source_set_callback (source, do_computation, NULL, NULL);\n" " id = g_source_attach (source, context);\n" " g_source_unref (source);\n" "\n" " /* The ID can be used with the same @context to\n" " * cancel the scheduled computation if needed. */\n" " return id;\n" "}\n" "\n" "static void\n" "do_computation (gpointer user_data)\n" "{\n" " /* … */\n" "}" #. (itstool) path: section/title #: C/main-contexts.page:412 #, fuzzy msgid "Using GMainContext in a Library" msgstr "Η περιήγηση κώδικα χρησιμοποιώντας τον περιηγητή συμβόλων" #. (itstool) path: section/p #: C/main-contexts.page:414 msgid "" "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 GSources are dispatched. " "There are various best practices which can be followed to aid this." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:422 msgid "" "Never iterate a context created outside the library, including the global-" "default or thread-default contexts. Otherwise, GSources created " "in the application may be dispatched when the application is not expecting " "it, causing re-entrancy problems for the application code." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:431 msgid "" "Always remove GSources 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." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:442 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:451 msgid "" "Use g_main_context_invoke() to ensure callbacks are dispatched " "in the right context. It’s much easier than manually using " "g_idle_source_new() to transfer work between contexts. (See: " ".)" msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:458 msgid "" "Libraries should never use g_main_context_default() (or, " "equivalently, pass NULL to a GMainContext-typed " "parameter). Always store and explicitly use a specific GMainContext, 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." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:468 msgid "" "Always write things asynchronously internally (using GTask where appropriate), and keep synchronous " "wrappers at the very top level of an API, where they can be implemented by " "calling g_main_context_iteration() on a specific " "GMainContext. Again, this makes future refactoring easier. This " "is demonstrated in the above example: the thread uses " "g_output_stream_write_async() rather than " "g_output_stream_write()." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:479 msgid "" "Always match pushes and pops of the thread-default main context: " "g_main_context_push_thread_default() and " "g_main_context_pop_thread_default()." msgstr "" #. (itstool) path: section/title #: C/main-contexts.page:487 msgid "Ensuring Functions are Called in the Right Context" msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:489 msgid "" "The ‘right context’ is the thread-default main context of the thread the " "function should be executing in. This assumes the typical case that " "every thread has a single main context running in a main loop. A " "main context effectively provides a work or message queue 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." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:503 msgid "" "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." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:511 msgid "" "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 message passing. This allows each thread to update its data at its " "leisure, which significantly simplifies locking." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:523 msgid "" "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." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:533 msgid "" "For example, the progress callback in g_file_copy_async() is documented as being called in the thread-default main " "context at the time of the initial call." msgstr "" #. (itstool) path: section/title #: C/main-contexts.page:542 #, fuzzy msgid "Principles of Invocation" msgstr "Κλήση ενέργειας" #. (itstool) path: section/p #: C/main-contexts.page:544 msgid "" "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 convenience method, " "g_main_context_invoke_full() should be used instead." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:551 msgid "" "A GSource has to be added to the " "target GMainContext, which will invoke the function when it’s " "dispatched. This GSource should almost always be an idle source " "created with g_idle_source_new(), 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." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:562 msgid "" "The GSource will be dispatched as soon as it’s ready, 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 g_source_set_priority(). The source will " "typically then be destroyed so the function is only executed once (though " "again, this doesn’t have to be the case)." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:574 msgid "" "Data can be passed between threads as the user_data passed to " "the GSource’s callback. This is set on the source using g_source_set_callback(), " "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." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:584 msgid "" "The example below demonstrates the underlying principles, but there are " "convenience methods explained below which simplify things." msgstr "" #. (itstool) path: example/code #: C/main-contexts.page:589 #, no-wrap msgid "" "\n" "/* Main function for the background thread, thread1. */\n" "static gpointer\n" "thread1_main (gpointer user_data)\n" "{\n" " GMainContext *thread1_main_context = user_data;\n" " GMainLoop *main_loop;\n" "\n" " /* Set up the thread’s context and run it forever. */\n" " g_main_context_push_thread_default (thread1_main_context);\n" "\n" " main_loop = g_main_loop_new (thread1_main_context, FALSE);\n" " g_main_loop_run (main_loop);\n" " g_main_loop_unref (main_loop);\n" "\n" " g_main_context_pop_thread_default (thread1_main_context);\n" " g_main_context_unref (thread1_main_context);\n" "\n" " return NULL;\n" "}\n" "\n" "/* A data closure structure to carry multiple variables between\n" " * threads. */\n" "typedef struct {\n" " gchar *some_string; /* owned */\n" " guint some_int;\n" " GObject *some_object; /* owned */\n" "} MyFuncData;\n" "\n" "static void\n" "my_func_data_free (MyFuncData *data)\n" "{\n" " g_free (data->some_string);\n" " g_clear_object (&data->some_object);\n" " g_free (data);\n" "}\n" "\n" "static void\n" "my_func (const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object)\n" "{\n" " /* Do something long and CPU intensive! */\n" "}\n" "\n" "/* Convert an idle callback into a call to my_func(). */\n" "static gboolean\n" "my_func_idle (gpointer user_data)\n" "{\n" " MyFuncData *data = user_data;\n" "\n" " my_func (data->some_string, data->some_int, data->some_object);\n" "\n" " return G_SOURCE_REMOVE;\n" "}\n" "\n" "/* Function to be called in the main thread to schedule a call to\n" " * my_func() in thread1, passing the given parameters along. */\n" "static void\n" "invoke_my_func (GMainContext *thread1_main_context,\n" " const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object)\n" "{\n" " GSource *idle_source;\n" " MyFuncData *data;\n" "\n" " /* Create a data closure to pass all the desired variables\n" " * between threads. */\n" " data = g_new0 (MyFuncData, 1);\n" " data->some_string = g_strdup (some_string);\n" " data->some_int = some_int;\n" " data->some_object = g_object_ref (some_object);\n" "\n" " /* Create a new idle source, set my_func() as the callback with\n" " * some data to be passed between threads, bump up the priority\n" " * and schedule it by attaching it to thread1’s context. */\n" " idle_source = g_idle_source_new ();\n" " g_source_set_callback (idle_source, my_func_idle, data,\n" " (GDestroyNotify) my_func_data_free);\n" " g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);\n" " g_source_attach (idle_source, thread1_main_context);\n" " g_source_unref (idle_source);\n" "}\n" "\n" "/* Main function for the main thread. */\n" "static void\n" "main (void)\n" "{\n" " GThread *thread1;\n" " GMainContext *thread1_main_context;\n" "\n" " /* Spawn a background thread and pass it a reference to its\n" " * GMainContext. Retain a reference for use in this thread\n" " * too. */\n" " thread1_main_context = g_main_context_new ();\n" " g_thread_new (\"thread1\", thread1_main,\n" " g_main_context_ref (thread1_main_context));\n" "\n" " /* Maybe set up your UI here, for example. */\n" "\n" " /* Invoke my_func() in the other thread. */\n" " invoke_my_func (thread1_main_context,\n" " \"some data which needs passing between threads\",\n" " 123456, some_object);\n" "\n" " /* Continue doing other work. */\n" "}" msgstr "" "\n" "/* Main function for the background thread, thread1. */\n" "static gpointer\n" "thread1_main (gpointer user_data)\n" "{\n" " GMainContext *thread1_main_context = user_data;\n" " GMainLoop *main_loop;\n" "\n" " /* Set up the thread’s context and run it forever. */\n" " g_main_context_push_thread_default (thread1_main_context);\n" "\n" " main_loop = g_main_loop_new (thread1_main_context, FALSE);\n" " g_main_loop_run (main_loop);\n" " g_main_loop_unref (main_loop);\n" "\n" " g_main_context_pop_thread_default (thread1_main_context);\n" " g_main_context_unref (thread1_main_context);\n" "\n" " return NULL;\n" "}\n" "\n" "/* A data closure structure to carry multiple variables between\n" " * threads. */\n" "typedef struct {\n" " gchar *some_string; /* owned */\n" " guint some_int;\n" " GObject *some_object; /* owned */\n" "} MyFuncData;\n" "\n" "static void\n" "my_func_data_free (MyFuncData *data)\n" "{\n" " g_free (data->some_string);\n" " g_clear_object (&data->some_object);\n" " g_free (data);\n" "}\n" "\n" "static void\n" "my_func (const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object)\n" "{\n" " /* Do something long and CPU intensive! */\n" "}\n" "\n" "/* Convert an idle callback into a call to my_func(). */\n" "static gboolean\n" "my_func_idle (gpointer user_data)\n" "{\n" " MyFuncData *data = user_data;\n" "\n" " my_func (data->some_string, data->some_int, data->some_object);\n" "\n" " return G_SOURCE_REMOVE;\n" "}\n" "\n" "/* Function to be called in the main thread to schedule a call to\n" " * my_func() in thread1, passing the given parameters along. */\n" "static void\n" "invoke_my_func (GMainContext *thread1_main_context,\n" " const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object)\n" "{\n" " GSource *idle_source;\n" " MyFuncData *data;\n" "\n" " /* Create a data closure to pass all the desired variables\n" " * between threads. */\n" " data = g_new0 (MyFuncData, 1);\n" " data->some_string = g_strdup (some_string);\n" " data->some_int = some_int;\n" " data->some_object = g_object_ref (some_object);\n" "\n" " /* Create a new idle source, set my_func() as the callback with\n" " * some data to be passed between threads, bump up the priority\n" " * and schedule it by attaching it to thread1’s context. */\n" " idle_source = g_idle_source_new ();\n" " g_source_set_callback (idle_source, my_func_idle, data,\n" " (GDestroyNotify) my_func_data_free);\n" " g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);\n" " g_source_attach (idle_source, thread1_main_context);\n" " g_source_unref (idle_source);\n" "}\n" "\n" "/* Main function for the main thread. */\n" "static void\n" "main (void)\n" "{\n" " GThread *thread1;\n" " GMainContext *thread1_main_context;\n" "\n" " /* Spawn a background thread and pass it a reference to its\n" " * GMainContext. Retain a reference for use in this thread\n" " * too. */\n" " thread1_main_context = g_main_context_new ();\n" " g_thread_new (\"thread1\", thread1_main,\n" " g_main_context_ref (thread1_main_context));\n" "\n" " /* Maybe set up your UI here, for example. */\n" "\n" " /* Invoke my_func() in the other thread. */\n" " invoke_my_func (thread1_main_context,\n" " \"some data which needs passing between threads\",\n" " 123456, some_object);\n" "\n" " /* Continue doing other work. */\n" "}" #. (itstool) path: example/p #: C/main-contexts.page:698 msgid "" "This invocation is uni-directional: it calls " "my_func() in thread1, 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." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:706 msgid "" "To maintain thread safety, data which is potentially accessed by multiple " "threads must make those accesses mutually exclusive using a mutex. Data " "potentially accessed by multiple threads: thread1_main_context, " "passed in the fork call to thread1_main; and some_object, a reference to which is passed in the data closure. Critically, GLib " "guarantees that GMainContext is thread safe, so sharing " "thread1_main_context between threads is safe. The example " "assumes that other code accessing some_object is thread safe." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:720 msgid "" "Note that some_string and some_int cannot be " "accessed from both threads, because copies of them are passed to " "thread1, 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 " "some_string." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:729 msgid "" "Similarly, a reference to some_object is transferred to " "thread1, which works around the issue of synchronizing " "destruction of the object (see )." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:735 msgid "" "g_idle_source_new() is used rather than the simpler " "g_idle_add() so the GMainContext to attach to can " "be specified." msgstr "" #. (itstool) path: section/title #: C/main-contexts.page:744 msgid "Convenience Method: g_main_context_invoke_full()" msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:748 msgid "" "This is simplified greatly by the convenience method, g_main_context_invoke_full(). It invokes a " "callback so that the specified GMainContext 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." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:757 msgid "" "g_main_context_invoke() can be used instead if the user data " "does not need to be freed by a GDestroyNotify callback after " "the invocation returns." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:764 msgid "" "Modifying the earlier example, the invoke_my_func() function " "can be replaced by the following:" msgstr "" #. (itstool) path: example/code #: C/main-contexts.page:769 #, no-wrap msgid "" "\n" "static void\n" "invoke_my_func (GMainContext *thread1_main_context,\n" " const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object)\n" "{\n" " MyFuncData *data;\n" "\n" " /* Create a data closure to pass all the desired variables\n" " * between threads. */\n" " data = g_new0 (MyFuncData, 1);\n" " data->some_string = g_strdup (some_string);\n" " data->some_int = some_int;\n" " data->some_object = g_object_ref (some_object);\n" "\n" " /* Invoke the function. */\n" " g_main_context_invoke_full (thread1_main_context,\n" " G_PRIORITY_DEFAULT, my_func_idle,\n" " data,\n" " (GDestroyNotify) my_func_data_free);\n" "}" msgstr "" "\n" "static void\n" "invoke_my_func (GMainContext *thread1_main_context,\n" " const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object)\n" "{\n" " MyFuncData *data;\n" "\n" " /* Create a data closure to pass all the desired variables\n" " * between threads. */\n" " data = g_new0 (MyFuncData, 1);\n" " data->some_string = g_strdup (some_string);\n" " data->some_int = some_int;\n" " data->some_object = g_object_ref (some_object);\n" "\n" " /* Invoke the function. */\n" " g_main_context_invoke_full (thread1_main_context,\n" " G_PRIORITY_DEFAULT, my_func_idle,\n" " data,\n" " (GDestroyNotify) my_func_data_free);\n" "}" #. (itstool) path: example/p #: C/main-contexts.page:792 msgid "" "Consider what happens if invoke_my_func() were called from " "thread1, rather than from the main thread. With the original " "implementation, the idle source would be added to thread1’s " "context and dispatched on the context’s next iteration (assuming no pending " "dispatches with higher priorities). With the improved implementation, " "g_main_context_invoke_full() will notice that the specified " "context is already owned by the thread (or ownership can be acquired by it), " "and will call my_func_idle() directly, rather than attaching a " "source to the context and delaying the invocation to the next context " "iteration." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:806 msgid "" "This subtle behavior difference doesn’t matter in most cases, but is worth " "bearing in mind since it can affect blocking behavior " "(invoke_my_func() would go from taking negligible time, to " "taking the same amount of time as my_func() before returning)." msgstr "" #. (itstool) path: section/title #: C/main-contexts.page:818 #, fuzzy msgid "Checking Threading" msgstr "Χωρίς καμία νηματοποίηση" #. (itstool) path: section/p #: C/main-contexts.page:820 msgid "" "It is useful to document which thread each function should be called in, in " "the form of an assertion:" msgstr "" #. (itstool) path: section/code #: C/main-contexts.page:824 #, no-wrap msgid "" "\n" "g_assert (g_main_context_is_owner (expected_main_context));" msgstr "" "\n" "g_assert (g_main_context_is_owner (expected_main_context));" #. (itstool) path: section/p #: C/main-contexts.page:827 msgid "" "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 debuging race conditions which can easily result from a function " "being called in the wrong thread." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:835 msgid "" "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 g_signal_emit() is synchronous, and doesn’t involve a main context at all." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:844 msgid "For example, instead of using the following when emitting a signal:" msgstr "" #. (itstool) path: example/code #: C/main-contexts.page:847 #, no-wrap msgid "" "\n" "guint param1; /* arbitrary example parameters */\n" "gchar *param2;\n" "guint retval = 0;\n" "\n" "g_signal_emit_by_name (my_object, \"some-signal\",\n" " param1, param2, &retval);" msgstr "" "\n" "guint param1; /* arbitrary example parameters */\n" "gchar *param2;\n" "guint retval = 0;\n" "\n" "g_signal_emit_by_name (my_object, \"some-signal\",\n" " param1, param2, &retval);" #. (itstool) path: example/p #: C/main-contexts.page:855 #, fuzzy msgid "The following can be used:" msgstr "Σε αυτό το παράδειγμα χρησιμοποιήσαμε το παρακάτω:" #. (itstool) path: example/code #: C/main-contexts.page:858 #, no-wrap msgid "" "\n" "static guint\n" "emit_some_signal (GObject *my_object,\n" " guint param1,\n" " const gchar *param2)\n" "{\n" " guint retval = 0;\n" "\n" " g_assert (g_main_context_is_owner (expected_main_context));\n" "\n" " g_signal_emit_by_name (my_object, \"some-signal\",\n" " param1, param2, &retval);\n" "\n" " return retval;\n" "}" msgstr "" "\n" "static guint\n" "emit_some_signal (GObject *my_object,\n" " guint param1,\n" " const gchar *param2)\n" "{\n" " guint retval = 0;\n" "\n" " g_assert (g_main_context_is_owner (expected_main_context));\n" "\n" " g_signal_emit_by_name (my_object, \"some-signal\",\n" " param1, param2, &retval);\n" "\n" " return retval;\n" "}" #. (itstool) path: section/title #: C/main-contexts.page:877 msgid "GTask" msgstr "GTask" #. (itstool) path: section/p #: C/main-contexts.page:879 msgid "" "GTask 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 some background thread, but not a " "specific one." msgstr "" #. (itstool) path: section/p #: C/main-contexts.page:886 msgid "" "GTask 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." msgstr "" #. (itstool) path: example/p #: C/main-contexts.page:894 msgid "" "By combining g_main_context_invoke_full() and GTask, " "it is possible to run a task in a specific context and effortlessly return " "its result to the current context:" msgstr "" #. (itstool) path: example/code #: C/main-contexts.page:900 #, no-wrap msgid "" "\n" "/* This will be invoked in thread1. */\n" "static gboolean\n" "my_func_idle (gpointer user_data)\n" "{\n" " GTask *task = G_TASK (user_data);\n" " MyFuncData *data;\n" " gboolean retval;\n" "\n" " /* Call my_func() and propagate its returned boolean to\n" " * the main thread. */\n" " data = g_task_get_task_data (task);\n" " retval = my_func (data->some_string, data->some_int,\n" " data->some_object);\n" " g_task_return_boolean (task, retval);\n" "\n" " return G_SOURCE_REMOVE;\n" "}\n" "\n" "/* Whichever thread this is invoked in, the @callback will be\n" " * invoked in, once my_func() has finished and returned a result. */\n" "static void\n" "invoke_my_func_with_result (GMainContext *thread1_main_context,\n" " const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data)\n" "{\n" " MyFuncData *data;\n" "\n" " /* Create a data closure to pass all the desired variables\n" " * between threads. */\n" " data = g_new0 (MyFuncData, 1);\n" " data->some_string = g_strdup (some_string);\n" " data->some_int = some_int;\n" " data->some_object = g_object_ref (some_object);\n" "\n" " /* Create a GTask to handle returning the result to the current\n" " * thread-default main context. */\n" " task = g_task_new (NULL, NULL, callback, user_data);\n" " g_task_set_task_data (task, data,\n" " (GDestroyNotify) my_func_data_free);\n" "\n" " /* Invoke the function. */\n" " g_main_context_invoke_full (thread1_main_context,\n" " G_PRIORITY_DEFAULT, my_func_idle,\n" " task,\n" " (GDestroyNotify) g_object_unref);\n" "}" msgstr "" "\n" "/* This will be invoked in thread1. */\n" "static gboolean\n" "my_func_idle (gpointer user_data)\n" "{\n" " GTask *task = G_TASK (user_data);\n" " MyFuncData *data;\n" " gboolean retval;\n" "\n" " /* Call my_func() and propagate its returned boolean to\n" " * the main thread. */\n" " data = g_task_get_task_data (task);\n" " retval = my_func (data->some_string, data->some_int,\n" " data->some_object);\n" " g_task_return_boolean (task, retval);\n" "\n" " return G_SOURCE_REMOVE;\n" "}\n" "\n" "/* Whichever thread this is invoked in, the @callback will be\n" " * invoked in, once my_func() has finished and returned a result. */\n" "static void\n" "invoke_my_func_with_result (GMainContext *thread1_main_context,\n" " const gchar *some_string,\n" " guint some_int,\n" " GObject *some_object,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data)\n" "{\n" " MyFuncData *data;\n" "\n" " /* Create a data closure to pass all the desired variables\n" " * between threads. */\n" " data = g_new0 (MyFuncData, 1);\n" " data->some_string = g_strdup (some_string);\n" " data->some_int = some_int;\n" " data->some_object = g_object_ref (some_object);\n" "\n" " /* Create a GTask to handle returning the result to the current\n" " * thread-default main context. */\n" " task = g_task_new (NULL, NULL, callback, user_data);\n" " g_task_set_task_data (task, data,\n" " (GDestroyNotify) my_func_data_free);\n" "\n" " /* Invoke the function. */\n" " g_main_context_invoke_full (thread1_main_context,\n" " G_PRIORITY_DEFAULT, my_func_idle,\n" " task,\n" " (GDestroyNotify) g_object_unref);\n" "}" #. (itstool) path: info/desc #: C/memory-management.page:17 msgid "Managing memory allocation and deallocation in C" msgstr "" #. (itstool) path: page/title #: C/memory-management.page:20 msgid "Memory Management" msgstr "Διαχείριση μνήμης" #. (itstool) path: page/p #: C/memory-management.page:50 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/memory-management.page:57 msgid "" "It is assumed that the reader is familiar with the idea of heap allocation " "of memory using malloc() and free(), and knows of " "the paired GLib equivalents, g_malloc() and g_free()." msgstr "" #. (itstool) path: synopsis/p #: C/memory-management.page:67 msgid "There are three situations to avoid, in order of descending importance:" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:72 msgid "Using memory after freeing it (use-after-free)." msgstr "" #. (itstool) path: item/p #: C/memory-management.page:73 #, fuzzy msgid "Using memory before allocating it." msgstr "Χωρίς μνήμη για κατανομή cookie\n" #. (itstool) path: item/p #: C/memory-management.page:74 msgid "Not freeing memory after allocating it (leaking)." msgstr "" #. (itstool) path: synopsis/p #: C/memory-management.page:77 msgid "Key principles, in no particular order:" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:82 msgid "" "Determine and document whether each variable is owned or unowned. They must " "never change from one to the other at runtime. ()" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:87 msgid "" "Determine and document the ownership transfers at function boundaries. " "()" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:91 msgid "" "Ensure that each assignment, function call and function return respects the " "relevant ownership transfers. (, , )" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:96 msgid "" "Use reference counting rather than explicit finalization where possible. " "()" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:100 msgid "" "Use GLib convenience functions like g_clear_object() where possible. ()" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:105 msgid "" "Do not split memory management across code paths. ()" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:109 msgid "" "Use the single-path cleanup pattern for large or complex functions. ()" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:113 msgid "" "Leaks should be checked for using Valgrind or the address sanitizer. ()" msgstr "" #. (itstool) path: section/title #: C/memory-management.page:121 #, fuzzy msgid "Principles of Memory Management" msgstr "Κανονική διαχείριση μνήμης C++" #. (itstool) path: section/p #: C/memory-management.page:123 msgid "" "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 ownership, which is the piece of code " "(such as a function, struct or object) which is responsible for freeing a " "piece of allocated memory (an allocation). Each allocation has " "exactly one owner; this owner may change as the program runs, by " "transferring ownership to another piece of code. Each variable is " "owned or unowned, 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." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:140 msgid "" "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 not freeing the unowned variables (see " "). The key question to answer for all " "memory is: which code has ownership of this memory?" msgstr "" #. (itstool) path: section/p #: C/memory-management.page:149 msgid "" "There is an important restriction here: variables must never change from owned to unowned (or vice-versa) at runtime. This " "restriction is key to simplifying memory management." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:155 msgid "For example, consider the functions:" msgstr "" #. (itstool) path: section/code #: C/memory-management.page:159 #, no-wrap msgid "" "gchar *generate_string (const gchar *template);\n" "void print_string (const gchar *str);" msgstr "" "gchar *generate_string (const gchar *template);\n" "void print_string (const gchar *str);" #. (itstool) path: section/p #: C/memory-management.page:162 msgid "" "The following code has been annotated to note where the ownership transfers " "happen:" msgstr "" #. (itstool) path: section/code #: C/memory-management.page:167 #, no-wrap msgid "" "gchar *my_str = NULL; /* owned */\n" "const gchar *template; /* unowned */\n" "GValue value = G_VALUE_INIT; /* owned */\n" "g_value_init (&value, G_TYPE_STRING);\n" "\n" "/* Transfers ownership of a string from the function to the variable. */\n" "template = \"XXXXXX\";\n" "my_str = generate_string (template);\n" "\n" "/* No ownership transfer. */\n" "print_string (my_str);\n" "\n" "/* Transfer ownership. We no longer have to free @my_str. */\n" "g_value_take_string (&value, my_str);\n" "\n" "/* We still have ownership of @value, so free it before it goes out of scope. */\n" "g_value_unset (&value);" msgstr "" "gchar *my_str = NULL; /* owned */\n" "const gchar *template; /* unowned */\n" "GValue value = G_VALUE_INIT; /* owned */\n" "g_value_init (&value, G_TYPE_STRING);\n" "\n" "/* Transfers ownership of a string from the function to the variable. */\n" "template = \"XXXXXX\";\n" "my_str = generate_string (template);\n" "\n" "/* No ownership transfer. */\n" "print_string (my_str);\n" "\n" "/* Transfer ownership. We no longer have to free @my_str. */\n" "g_value_take_string (&value, my_str);\n" "\n" "/* We still have ownership of @value, so free it before it goes out of scope. */\n" "g_value_unset (&value);" #. (itstool) path: section/p #: C/memory-management.page:185 msgid "" "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 not have ownership, and " "must not free the variables before going out of scope. Similarly, " "ownership must not be transferred to them on assignment." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:195 msgid "" "Secondly, the variable type modifiers reflect whether they transfer " "ownership: because my_str is owned by the local scope, it has " "type gchar, whereas template is const " "to denote it is unowned. Similarly, the template parameter of " "generate_string() and the str parameter of " "print_string() are const because no ownership is " "transferred when those functions are called. As ownership is " "transferred for the string parameter of g_value_take_string(), " "we can expect its type to be gchar." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:208 msgid "" "(Note that this is not the case for GObjects and subclasses, which can never be const. It is only the " "case for strings and simple structs.)" msgstr "" #. (itstool) path: section/p #: C/memory-management.page:216 msgid "" "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 g_value_take_string(). " "Note that different libraries use different conventions, as shown below:" msgstr "" #. (itstool) path: td/p #: C/memory-management.page:229 msgid "Function name" msgstr "Όνομα συνάρτησης" #. (itstool) path: td/p #: C/memory-management.page:230 msgid "Convention 1 (standard)" msgstr "" #. (itstool) path: td/p #: C/memory-management.page:231 msgid "Convention 2 (alternate)" msgstr "" #. (itstool) path: td/p #: C/memory-management.page:232 msgid "Convention 3 (gdbus-codegen)" msgstr "" #. (itstool) path: td/p #: C/memory-management.page:237 msgid "get" msgstr "get" #. (itstool) path: td/p #: C/memory-management.page:238 C/memory-management.page:254 #: C/memory-management.page:259 C/memory-management.page:260 #: C/memory-management.page:261 #, fuzzy msgid "No transfer" msgstr "Μεταφορά" #. (itstool) path: td/p #: C/memory-management.page:239 #, fuzzy msgid "Any transfer" msgstr "Μεταφορά" #. (itstool) path: td/p #: C/memory-management.page:240 C/memory-management.page:245 #: C/memory-management.page:266 C/memory-management.page:273 #: C/memory-management.page:274 C/memory-management.page:275 #, fuzzy msgid "Full transfer" msgstr "Μεταφορά" #. (itstool) path: td/p #: C/memory-management.page:244 msgid "dup" msgstr "dup" #. (itstool) path: td/p #: C/memory-management.page:246 C/memory-management.page:247 #: C/memory-management.page:252 C/memory-management.page:253 #: C/memory-management.page:267 C/memory-management.page:268 #, fuzzy msgid "Unused" msgstr "Δε χρησιμοποιούνται" #. (itstool) path: td/p #: C/memory-management.page:251 msgid "peek" msgstr "peek" #. (itstool) path: td/p #: C/memory-management.page:258 msgid "set" msgstr "set" #. (itstool) path: td/p #: C/memory-management.page:265 msgid "take" msgstr "take" #. (itstool) path: td/p #: C/memory-management.page:272 msgid "steal" msgstr "steal" #. (itstool) path: section/p #: C/memory-management.page:280 msgid "" "Ideally, all functions have a (transfer) introspection annotation 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:" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:288 msgid "" "If the type has an introspection (transfer) annotation, look at " "that." msgstr "" #. (itstool) path: item/p #: C/memory-management.page:292 msgid "Otherwise, if the type is const, there is no transfer." msgstr "" #. (itstool) path: item/p #: C/memory-management.page:295 msgid "" "Otherwise, if the function documentation explicitly specifies the return " "value must be freed, there is full or container transfer." msgstr "" #. (itstool) path: item/p #: C/memory-management.page:299 msgid "" "Otherwise, if the function is named ‘dup’, ‘take’ or ‘steal’, there is full " "or container transfer." msgstr "" #. (itstool) path: item/p #: C/memory-management.page:303 msgid "Otherwise, if the function is named ‘peek’, there is no transfer." msgstr "" #. (itstool) path: item/p #: C/memory-management.page:306 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:314 msgid "" "Given this ownership and transfer infrastructure, the correct approach to " "memory allocation can be mechanically determined for each situation. In each " "case, the copy() function must be appropriate to the data type, " "for example g_strdup() for strings, or g_object_ref() for GObjects." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:322 msgid "" "When thinking about ownership transfer, malloc()/free() 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 ." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:331 #, fuzzy msgid "Assignments" msgstr "Όλες οι εργασίες που έχουν ανατεθεί σε αυτή την ομάδα θα χαθούν." #. (itstool) path: td/p #: C/memory-management.page:338 #, fuzzy msgid "Assignment from/to" msgstr "Εκχώρηση" #. (itstool) path: td/p #: C/memory-management.page:339 #, fuzzy msgid "Owned destination" msgstr "Προορισμός" #. (itstool) path: td/p #: C/memory-management.page:340 #, fuzzy msgid "Unowned destination" msgstr "Πρ_οορισμός:" #. (itstool) path: td/p #: C/memory-management.page:346 C/memory-management.page:394 #: C/memory-management.page:441 #, fuzzy msgid "Owned source" msgstr "Ανήκει σε _χρήστη" #. (itstool) path: td/p #: C/memory-management.page:348 #, fuzzy msgid "Copy or move the source to the destination." msgstr "Διαδρομές πηγής/προορισμού:" #. (itstool) path: td/code #: C/memory-management.page:351 #, no-wrap msgid "owned_dest = copy (owned_src)" msgstr "owned_dest = copy (owned_src)" #. (itstool) path: td/code #: C/memory-management.page:352 #, no-wrap msgid "owned_dest = owned_src; owned_src = NULL" msgstr "owned_dest = owned_src; owned_src = NULL" #. (itstool) path: td/p #: C/memory-management.page:355 msgid "" "Pure assignment, assuming the unowned variable is not used after the owned " "one is freed." msgstr "" #. (itstool) path: td/code #: C/memory-management.page:359 #, no-wrap msgid "unowned_dest = owned_src" msgstr "unowned_dest = owned_src" #. (itstool) path: td/p #: C/memory-management.page:364 C/memory-management.page:411 #: C/memory-management.page:457 #, fuzzy msgid "Unowned source" msgstr "Δεν υπάρχει τέτοια πηγή" #. (itstool) path: td/p #: C/memory-management.page:366 msgid "Copy the source to the destination." msgstr "Αντιγραφή της πηγής στον προορισμό." #. (itstool) path: td/code #: C/memory-management.page:367 #, no-wrap msgid "owned_dest = copy (unowned_src)" msgstr "owned_dest = copy (unowned_src)" #. (itstool) path: td/p #: C/memory-management.page:370 #, fuzzy msgid "Pure assignment." msgstr "Καθαρή συμβολομετάφραση" #. (itstool) path: td/code #: C/memory-management.page:371 #, no-wrap msgid "unowned_dest = unowned_src" msgstr "unowned_dest = unowned_src" #. (itstool) path: section/title #: C/memory-management.page:379 msgid "Function Calls" msgstr "Κλήσεις συναρτήσεων" #. (itstool) path: td/p #: C/memory-management.page:386 #, fuzzy msgid "Call from/to" msgstr "Κλήση από %s" #. (itstool) path: td/p #: C/memory-management.page:387 #, fuzzy msgid "Transfer full parameter" msgstr "ΠΑΡΑΜΕΤΡΟΣ" #. (itstool) path: td/p #: C/memory-management.page:388 #, fuzzy msgid "Transfer none parameter" msgstr "ΠΑΡΑΜΕΤΡΟΣ" #. (itstool) path: td/p #: C/memory-management.page:396 #, fuzzy msgid "Copy or move the source for the parameter." msgstr "Αντιγραφή ή μετακίνηση αρχείων και φακέλων" #. (itstool) path: td/code #: C/memory-management.page:399 #, no-wrap msgid "function_call (copy (owned_src))" msgstr "function_call (copy (owned_src))" #. (itstool) path: td/code #: C/memory-management.page:400 #, no-wrap msgid "function_call (owned_src); owned_src = NULL" msgstr "function_call (owned_src); owned_src = NULL" #. (itstool) path: td/p #: C/memory-management.page:403 C/memory-management.page:417 #, fuzzy msgid "Pure parameter passing." msgstr "Καθαρή συμβολομετάφραση" #. (itstool) path: td/code #: C/memory-management.page:406 #, no-wrap msgid "function_call (owned_src)" msgstr "function_call (owned_src)" #. (itstool) path: td/p #: C/memory-management.page:413 #, fuzzy msgid "Copy the source for the parameter." msgstr "ΠΑΡΑΜΕΤΡΟΣ" #. (itstool) path: td/code #: C/memory-management.page:414 #, no-wrap msgid "function_call (copy (unowned_src))" msgstr "function_call (copy (unowned_src))" #. (itstool) path: td/code #: C/memory-management.page:418 #, no-wrap msgid "function_call (unowned_src)" msgstr "function_call (unowned_src)" #. (itstool) path: section/title #: C/memory-management.page:426 #, fuzzy msgid "Function Returns" msgstr "Η συνάρτηση YEAR επιστρέφει το μέρος του έτους της @{date}." #. (itstool) path: td/p #: C/memory-management.page:433 #, fuzzy msgid "Return from/to" msgstr "ASN.1 εσφαλμένη επιστροφή από gmtime" #. (itstool) path: td/p #: C/memory-management.page:434 #, fuzzy msgid "Transfer full return" msgstr "Μεταφορά" #. (itstool) path: td/p #: C/memory-management.page:435 #, fuzzy msgid "Transfer none return" msgstr "Μεταφορά" #. (itstool) path: td/p #: C/memory-management.page:443 #, fuzzy msgid "Pure variable return." msgstr "Καθαρή συμβολομετάφραση" #. (itstool) path: td/code #: C/memory-management.page:446 #, no-wrap msgid "return owned_src" msgstr "return owned_src" #. (itstool) path: td/p #: C/memory-management.page:449 msgid "" "Invalid. The source needs to be freed, so the return value would use freed " "memory — a use-after-free error." msgstr "" #. (itstool) path: td/p #: C/memory-management.page:459 #, fuzzy msgid "Copy the source for the return." msgstr "Αντίγραφο προέλευσης δεδομένων" #. (itstool) path: td/code #: C/memory-management.page:460 #, no-wrap msgid "return copy (unowned_src)" msgstr "return copy (unowned_src)" #. (itstool) path: td/p #: C/memory-management.page:463 #, fuzzy msgid "Pure variable passing." msgstr "Καθαρή συμβολομετάφραση" #. (itstool) path: td/code #: C/memory-management.page:464 #, no-wrap msgid "return unowned_src" msgstr "return unowned_src" #. (itstool) path: section/p #: C/memory-management.page:475 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:482 msgid "" "The best way to document ownership transfer is to use the (transfer) annotation introduced by gobject-" "introspection. 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 (transfer) " "annotations. By doing so, the introspection tools can also read the " "annotations and use them to correctly introspect the API." msgstr "" #. (itstool) path: section/code #: C/memory-management.page:497 #, no-wrap msgid "" "/**\n" " * g_value_take_string:\n" " * @value: (transfer none): an initialized #GValue\n" " * @str: (transfer full): string to set it to\n" " *\n" " * Function documentation goes here.\n" " */\n" "\n" "/**\n" " * generate_string:\n" " * @template: (transfer none): a template to follow when generating the string\n" " *\n" " * Function documentation goes here.\n" " *\n" " * Returns: (transfer full): a newly generated string\n" " */" msgstr "" "/**\n" " * g_value_take_string:\n" " * @value: (transfer none): an initialized #GValue\n" " * @str: (transfer full): string to set it to\n" " *\n" " * Function documentation goes here.\n" " */\n" "\n" "/**\n" " * generate_string:\n" " * @template: (transfer none): a template to follow when generating the string\n" " *\n" " * Function documentation goes here.\n" " *\n" " * Returns: (transfer full): a newly generated string\n" " */" #. (itstool) path: section/p #: C/memory-management.page:514 msgid "" "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." msgstr "" #. (itstool) path: section/code #: C/memory-management.page:519 #, no-wrap msgid "" "GObject *some_owned_object = NULL; /* owned */\n" "GObject *some_unowned_object; /* unowned */" msgstr "" "GObject *some_owned_object = NULL; /* owned */\n" "GObject *some_unowned_object; /* unowned */" #. (itstool) path: section/p #: C/memory-management.page:522 msgid "" "The documentation for is similarly only a " "convention; it includes the type of the contained elements too:" msgstr "" #. (itstool) path: section/code #: C/memory-management.page:526 #, no-wrap msgid "" "GPtrArray/*<owned gchar*>*/ *some_unowned_string_array; /* unowned */\n" "GPtrArray/*<owned gchar*>*/ *some_owned_string_array = NULL; /* owned */\n" "GPtrArray/*<unowned GObject*>*/ *some_owned_object_array = NULL; /* owned */" msgstr "" "GPtrArray/*<owned gchar*>*/ *some_unowned_string_array; /* unowned */\n" "GPtrArray/*<owned gchar*>*/ *some_owned_string_array = NULL; /* owned */\n" "GPtrArray/*<unowned GObject*>*/ *some_owned_object_array = NULL; /* owned */" #. (itstool) path: section/p #: C/memory-management.page:530 msgid "" "Note also that owned variables should always be initialized so that freeing " "them is more convenient. See ." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:536 msgid "" "Also note that some types, for example basic C types like strings, can have " "the const modifier added if they are unowned, to take advantage " "of compiler warnings resulting from assigning those variables to owned " "variables (which must not use the const modifier). If " "so, the /* unowned */ comment may be omitted." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:546 #, fuzzy msgid "Reference Counting" msgstr "" "Στον stop_playing που καλείται όταν η λήξη χρόνου περάσει, η " "διοχέτευση σταματά και έτσι δεν υπάρχει κανένας ήχος εξόδου πια. Καθώς το " "GStreamermm χρησιμοποιεί μετρητή αναφοράς μέσα από το αντικείμενο " "Glib::RefPtr, η μνήμη αυτόματα ελευθερώνεται μόλις η κλάση " "Sound καταστραφεί." #. (itstool) path: section/p #: C/memory-management.page:548 msgid "" "As well as conventional malloc()/free()-style " "types, GLib has various reference counted types — " "GObject being a prime example." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:555 msgid "" "The concepts of ownership and transfer apply just as well to reference " "counted types as they do to allocated types. A scope owns a " "reference counted type if it holds a strong reference to the instance (for " "example by calling g_object_ref()). An instance can be ‘copied’ by calling g_object_ref() again. Ownership can be freed with " "g_object_unref() — even though this may not actually " "finalize the instance, it frees the current scope’s ownership of that " "instance." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:569 msgid "" "See for a convenient way of handling " "GObject references." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:574 msgid "" "There are other reference counted types in GLib, such as " "GHashTable (using " "g_hash_table_ref() and " "g_hash_table_unref()), or GVariant " "( g_variant_ref(), " "g_variant_unref()). Some types, like GHashTable, 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." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:596 #, fuzzy msgid "Floating References" msgstr "Αναφορές" #. (itstool) path: section/p #: C/memory-management.page:598 msgid "" "Classes which are derived from GInitiallyUnowned, as opposed to GObject have an initial reference which is " "floating, meaning that no code owns the reference. As soon as g_object_ref_sink() is " "called on the object, the floating reference is converted to a strong " "reference, and the calling code assumes ownership of the object." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:610 msgid "" "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 g_object_unref() to drop all " "the strong references would result in a lot of code." msgstr "" #. (itstool) path: example/p #: C/memory-management.page:618 msgid "Floating references allow the following code to be simplified:" msgstr "" #. (itstool) path: example/code #: C/memory-management.page:621 #, no-wrap msgid "" "GtkWidget *new_widget;\n" "\n" "new_widget = gtk_some_widget_new ();\n" "gtk_container_add (some_container, new_widget);\n" "g_object_unref (new_widget);" msgstr "" "GtkWidget *new_widget;\n" "\n" "new_widget = gtk_some_widget_new ();\n" "gtk_container_add (some_container, new_widget);\n" "g_object_unref (new_widget);" #. (itstool) path: example/p #: C/memory-management.page:627 msgid "" "Instead, the following code can be used, with the GtkContainer " "assuming ownership of the floating reference:" msgstr "" #. (itstool) path: example/code #: C/memory-management.page:632 #, no-wrap msgid "" "\n" "gtk_container_add (some_container, gtk_some_widget_new ());" msgstr "" "\n" "gtk_container_add (some_container, gtk_some_widget_new ());" #. (itstool) path: section/p #: C/memory-management.page:636 msgid "" "Floating references are only used by a few APIs — in particular, " "GtkWidget and all its subclasses. You must learn which APIs " "support it, and which APIs consume floating references, and only use them " "together." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:643 msgid "" "Note that g_object_ref_sink() is equivalent to " "g_object_ref() when called on a non-floating reference, making " "gtk_container_add() no different from any other function in " "such cases." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:650 msgid "" "See the GObject manual for more " "information on floating references." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:658 #, fuzzy msgid "Convenience Functions" msgstr "" "Οι μακροεντολές _CTOR_DEFAULT() και " "_WRAP_CTOR() προσθέτουν κατασκευαστές συσκευάζοντας τις " "συγκεκριμένες συναρτήσεις C *_new(). Αυτές οι " "μακροεντολές θεωρούν ότι το αντικείμενο C έχει ιδιότητες με τα ίδια ονόματα " "όπως οι παράμετροι συνάρτησης, όπως συνήθως συμβαίνει, έτσι ώστε να μπορεί " "να παράσχει τις παραμέτρους άμεσα σε μια κλήση g_object_new(). Αυτοί οι κατασκευαστές στην πραγματικότητα δεν καλούν ποτέ τις " "συναρτήσεις C *_new(), επειδή η gtkmm πρέπει στην " "πραγματικότητα να αρχικοποιήσει παράγωγους GTypes και οι συναρτήσεις C " "*_new() νοούνται μόνο ως συναρτήσεις διευκόλυνσης για " "προγραμματιστές C." #. (itstool) path: section/p #: C/memory-management.page:660 msgid "" "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)." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:669 msgid "g_clear_object()" msgstr "g_clear_object()" #. (itstool) path: section/p #: C/memory-management.page:671 msgid "" " g_clear_object() is a " "version of g_object_unref() which unrefs a GObject and then clears the pointer to it to " "NULL." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:679 msgid "" "This makes it easier to implement code that guarantees a GObject pointer is " "always either NULL, or has ownership of a GObject (but which " "never points to a GObject it no longer owns)." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:685 msgid "" "By initialising all owned GObject pointers to NULL, freeing " "them at the end of the scope is as simple as calling g_clear_object() without any checks, as discussed in :" msgstr "" #. (itstool) path: section/code #: C/memory-management.page:691 #, no-wrap msgid "" "void\n" "my_function (void)\n" "{\n" " GObject *some_object = NULL; /* owned */\n" "\n" " if (rand ())\n" " {\n" " some_object = create_new_object ();\n" " /* do something with the object */\n" " }\n" "\n" " g_clear_object (&some_object);\n" "}" msgstr "" "void\n" "my_function (void)\n" "{\n" " GObject *some_object = NULL; /* owned */\n" "\n" " if (rand ())\n" " {\n" " some_object = create_new_object ();\n" " /* do something with the object */\n" " }\n" "\n" " g_clear_object (&some_object);\n" "}" #. (itstool) path: section/title #: C/memory-management.page:707 msgid "g_list_free_full()" msgstr "g_list_free_full()" #. (itstool) path: section/p #: C/memory-management.page:709 msgid "" " g_list_free_full() frees " "all the elements in a linked list, and all their data. It is much " "more convenient than iterating through the list to free all the elements’ " "data, then calling g_list_free() to " "free the GList elements themselves." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:721 msgid "g_hash_table_new_full()" msgstr "g_hash_table_new_full()" #. (itstool) path: section/p #: C/memory-management.page:723 msgid "" " g_hash_table_new_full() is a " "newer version of g_hash_table_new() " "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 g_hash_table_remove()." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:734 msgid "" "Essentially, it simplifies memory management of keys and values to the " "question of whether they are present in the hash table. See for a discussion on ownership of elements within " "container types." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:741 msgid "" "A similar function exists for GPtrArray: g_ptr_array_new_with_free_func()." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:750 #, fuzzy msgid "Container Types" msgstr "" "Ένα Gtk.Window είναι από μόνο του ένα είδος περιέκτη, αλλά " "μπορείτε να τοποθετήσετε μόνο ένα γραφικό στοιχείο άμεσα πάνω του. Θα θέλαμε " "να είχαμε δύο γραφικά στοιχεία, μια εικόνα και ένα κουμπί, άρα θα πρέπει να " "τοποθετήσουμε έναν υποδοχέα \"υψηλότερης χωρητικότητας\" μέσα στο παράθυρο " "για να κρατάει τα άλλα γραφικά στοιχεία. Ένας αριθμός από τύπους " "περιεκτών είναι διαθέσιμοι, αλλά θα χρησιμοποιήσουμε εδώ ένα " "Gtk.Box. Ένα Gtk.Box μπορεί να κρατήσει πολλά " "γραφικά στοιχεία, οργανωμένα οριζόντια ή κάθετα. Μπορείτε να κάνετε και πιο " "περίπλοκες διατάξεις βάζοντας πολλά πλαίσια το ένα μέσα στο άλλο κ.ο.κ." #. (itstool) path: section/p #: C/memory-management.page:752 msgid "" "When using container types, such as GPtrArray or GList, 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)." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:762 msgid "" "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 are used for types like GPtrArray and " "GHashTable." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:770 msgid "" "If elements in a container are owned, 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 g_ptr_array_add() " "is effectively:" msgstr "" #. (itstool) path: section/code #: C/memory-management.page:776 #, no-wrap msgid "" "/**\n" " * g_ptr_array_add:\n" " * @array: a #GPtrArray\n" " * @str: (transfer full): string to add\n" " */\n" "void\n" "g_ptr_array_add (GPtrArray *array,\n" " gchar *str);" msgstr "" "/**\n" " * g_ptr_array_add:\n" " * @array: a #GPtrArray\n" " * @str: (transfer full): string to add\n" " */\n" "void\n" "g_ptr_array_add (GPtrArray *array,\n" " gchar *str);" #. (itstool) path: section/p #: C/memory-management.page:785 msgid "" "So, for example, constant (unowned) strings must be added to the array using " "g_ptr_array_add (array, g_strdup (\"constant string\"))." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:790 msgid "Whereas if the elements are unowned, the definition is effectively:" msgstr "" #. (itstool) path: section/code #: C/memory-management.page:793 #, no-wrap msgid "" "/**\n" " * g_ptr_array_add:\n" " * @array: a #GPtrArray\n" " * @str: (transfer none): string to add\n" " */\n" "void\n" "g_ptr_array_add (GPtrArray *array,\n" " const gchar *str);" msgstr "" "/**\n" " * g_ptr_array_add:\n" " * @array: a #GPtrArray\n" " * @str: (transfer none): string to add\n" " */\n" "void\n" "g_ptr_array_add (GPtrArray *array,\n" " const gchar *str);" #. (itstool) path: section/p #: C/memory-management.page:802 msgid "" "Here, constant strings can be added without copying them: " "g_ptr_array_add (array, \"constant string\")." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:807 msgid "" "See for examples of comments to add to " "variable definitions to annotate them with the element type and ownership." msgstr "" #. (itstool) path: section/title #: C/memory-management.page:814 #, fuzzy msgid "Single-Path Cleanup" msgstr "_Καθαρισμός μηνυμάτων που είναι πιο παλιά από" #. (itstool) path: section/p #: C/memory-management.page:816 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:827 msgid "This approach has two requirements:" msgstr "" #. (itstool) path: item/p #: C/memory-management.page:831 msgid "" "The function returns from a single point, and uses goto to " "reach that point from other paths." msgstr "" #. (itstool) path: item/p #: C/memory-management.page:835 msgid "" "All owned variables are set to NULL when initialized or when " "ownership is transferred away from them." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:841 msgid "" "The example below is for a small function (for brevity), but should " "illustrate the principles for application of the pattern to larger functions:" msgstr "" #. (itstool) path: listing/title #: C/memory-management.page:848 #, fuzzy msgid "Single-Path Cleanup Example" msgstr "Παράδειγμα διαδρομής: " #. (itstool) path: listing/desc #: C/memory-management.page:849 msgid "Example of implementing single-path cleanup for a simple function" msgstr "" #. (itstool) path: listing/code #: C/memory-management.page:852 #, no-wrap msgid "" "GObject *\n" "some_function (GError **error)\n" "{\n" " gchar *some_str = NULL; /* owned */\n" " GObject *temp_object = NULL; /* owned */\n" " const gchar *temp_str;\n" " GObject *my_object = NULL; /* owned */\n" " GError *child_error = NULL; /* owned */\n" "\n" " temp_object = generate_object ();\n" " temp_str = \"example string\";\n" "\n" " if (rand ())\n" " {\n" " some_str = g_strconcat (temp_str, temp_str, NULL);\n" " }\n" " else\n" " {\n" " some_operation_which_might_fail (&child_error);\n" "\n" " if (child_error != NULL)\n" " {\n" " goto done;\n" " }\n" "\n" " my_object = generate_wrapped_object (temp_object);\n" " }\n" "\n" "done:\n" " /* Here, @some_str is either NULL or a string to be freed, so can be passed to\n" " * g_free() unconditionally.\n" " *\n" " * Similarly, @temp_object is either NULL or an object to be unreffed, so can\n" " * be passed to g_clear_object() unconditionally. */\n" " g_free (some_str);\n" " g_clear_object (&temp_object);\n" "\n" " /* The pattern can also be used to ensure that the function always returns\n" " * either an error or a return value (but never both). */\n" " if (child_error != NULL)\n" " {\n" " g_propagate_error (error, child_error);\n" " g_clear_object (&my_object);\n" " }\n" "\n" " return my_object;\n" "}" msgstr "" "GObject *\n" "some_function (GError **error)\n" "{\n" " gchar *some_str = NULL; /* owned */\n" " GObject *temp_object = NULL; /* owned */\n" " const gchar *temp_str;\n" " GObject *my_object = NULL; /* owned */\n" " GError *child_error = NULL; /* owned */\n" "\n" " temp_object = generate_object ();\n" " temp_str = \"example string\";\n" "\n" " if (rand ())\n" " {\n" " some_str = g_strconcat (temp_str, temp_str, NULL);\n" " }\n" " else\n" " {\n" " some_operation_which_might_fail (&child_error);\n" "\n" " if (child_error != NULL)\n" " {\n" " goto done;\n" " }\n" "\n" " my_object = generate_wrapped_object (temp_object);\n" " }\n" "\n" "done:\n" " /* Here, @some_str is either NULL or a string to be freed, so can be passed to\n" " * g_free() unconditionally.\n" " *\n" " * Similarly, @temp_object is either NULL or an object to be unreffed, so can\n" " * be passed to g_clear_object() unconditionally. */\n" " g_free (some_str);\n" " g_clear_object (&temp_object);\n" "\n" " /* The pattern can also be used to ensure that the function always returns\n" " * either an error or a return value (but never both). */\n" " if (child_error != NULL)\n" " {\n" " g_propagate_error (error, child_error);\n" " g_clear_object (&my_object);\n" " }\n" "\n" " return my_object;\n" "}" #. (itstool) path: section/title #: C/memory-management.page:903 #, fuzzy msgid "Verification" msgstr "Εισάγετε κωδικό επιβεβαίωσης:" #. (itstool) path: section/p #: C/memory-management.page:905 msgid "" "Memory leaks can be checked for in two ways: static analysis, and runtime " "leak checking." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:910 msgid "" "Static analysis with tools like Coverity, the Clang static " "analyzer or Tartan 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." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:924 msgid "" "Runtime leak checking is done using Valgrind, using its memcheck 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." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:933 msgid "" "If compiling with a recent version of Clang or GCC, the address sanitizer 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." msgstr "" #. (itstool) path: section/p #: C/memory-management.page:942 msgid "" "See for more information on using Valgrind." msgstr "" #. (itstool) path: credit/years #: C/namespacing.page:12 msgid "2015, 2016" msgstr "2015, 2016" #. (itstool) path: info/desc #: C/namespacing.page:17 msgid "Avoiding symbol conflicts between libraries by namespacing all APIs" msgstr "" #. (itstool) path: page/title #: C/namespacing.page:22 msgid "Namespacing" msgstr "" #. (itstool) path: synopsis/p #: C/namespacing.page:27 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/namespacing.page:36 msgid "GObject APIs" msgstr "GObject API" #. (itstool) path: section/p #: C/namespacing.page:38 msgid "" "Consistent and complete namespacing of symbols (functions and types) and " "files is important for two key reasons:" msgstr "" #. (itstool) path: item/p #: C/namespacing.page:43 msgid "" "Establishing a convention which means developers have to learn fewer symbol " "names to use the library — they can guess them reliably instead." msgstr "" #. (itstool) path: item/p #: C/namespacing.page:47 msgid "" "Ensuring symbols from two projects do not conflict if included in the same " "file." msgstr "" #. (itstool) path: section/p #: C/namespacing.page:53 msgid "" "The second point is important — imagine what would happen if every project " "exported a function called create_object(). 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." msgstr "" #. (itstool) path: section/p #: C/namespacing.page:63 msgid "" "The conventions below should be used for namespacing all symbols. They are " " used in all GLib-based projects, so should be familiar to a " "lot of developers:" msgstr "" #. (itstool) path: item/p #: C/namespacing.page:70 msgid "Functions should use lower_case_with_underscores." msgstr "" #. (itstool) path: item/p #: C/namespacing.page:73 msgid "" "Structures, types and objects should use CamelCaseWithoutUnderscores." msgstr "" #. (itstool) path: item/p #: C/namespacing.page:77 msgid "" "Macros and constants should use UPPER_CASE_WITH_UNDERSCORES." msgstr "" #. (itstool) path: item/p #: C/namespacing.page:81 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/namespacing.page:86 msgid "All methods of a class should also be prefixed with the class name." msgstr "" #. (itstool) path: section/p #: C/namespacing.page:91 msgid "" "Additionally, public headers should be included from a subdirectory, " "effectively namespacing the header files. For example, instead of " "#include <abc.h>, a project should allow its users to use " "#include <namespace/abc.h>." msgstr "" #. (itstool) path: section/p #: C/namespacing.page:98 msgid "" "Some projects namespace their headers within this subdirectory — for " "example, #include <namespace/ns-abc.h> instead of " "#include <namespace/abc.h>. This is redundant, but " "harmless." msgstr "" #. (itstool) path: section/p #: C/namespacing.page:105 msgid "" "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:" msgstr "" #. (itstool) path: item/p #: C/namespacing.page:111 msgid "" "$(includedir)/walbottle-$API_MAJOR/walbottle/" "schema.h" msgstr "" "$(includedir)/walbottle-$API_MAJOR/walbottle/" "schema.h" #. (itstool) path: item/p #: C/namespacing.page:114 msgid "" "$(includedir)/walbottle-$API_MAJOR/walbottle/" "writer.h" msgstr "" "$(includedir)/walbottle-$API_MAJOR/walbottle/" "writer.h" #. (itstool) path: section/p #: C/namespacing.page:119 msgid "" "(The use of $API_MAJOR above is for parallel installability.)" msgstr "" #. (itstool) path: section/p #: C/namespacing.page:124 msgid "" "For the schema class, the following symbols would be exported (amongst " "others), following GObject conventions:" msgstr "" #. (itstool) path: item/p #: C/namespacing.page:129 msgid "WblSchema structure" msgstr "Δομή WblSchema" #. (itstool) path: item/p #: C/namespacing.page:130 msgid "WblSchemaClass structure" msgstr "Δομή WblSchemaClass" #. (itstool) path: item/p #: C/namespacing.page:131 msgid "WBL_TYPE_SCHEMA macro" msgstr "Μακροεντολή WBL_TYPE_SCHEMA" #. (itstool) path: item/p #: C/namespacing.page:132 msgid "WBL_IS_SCHEMA macro" msgstr "Μακροεντολή WBL_IS_SCHEMA" #. (itstool) path: item/p #: C/namespacing.page:133 msgid "wbl_schema_get_type function" msgstr "Συνάρτηση wbl_schema_get_type" #. (itstool) path: item/p #: C/namespacing.page:134 msgid "wbl_schema_new function" msgstr "Συνάρτηση wbl_schema_new" #. (itstool) path: item/p #: C/namespacing.page:135 msgid "wbl_schema_load_from_data function" msgstr "Συνάρτηση wbl_schema_load_from_data" #. (itstool) path: credit/name #: C/parallel-installability.page:10 msgid "Havoc Pennington" msgstr "Havoc Pennington" #. (itstool) path: credit/years #: C/parallel-installability.page:12 msgid "2002" msgstr "2002" #. (itstool) path: info/desc #: C/parallel-installability.page:25 msgid "Writing libraries to be future proof through parallel installation" msgstr "" #. (itstool) path: page/title #: C/parallel-installability.page:30 msgid "Parallel Installability" msgstr "Παράλληλη εγκατάσταση" #. (itstool) path: synopsis/p #: C/parallel-installability.page:35 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:43 msgid "" "Ensure all versions of a library are parallel installable. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:47 msgid "Version all files installed by a library. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:51 msgid "" "Keep package version numbers separate from soname or libtool version " "numbers. Be clear which part of the package version number changes with the " "API. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:57 msgid "" "Install C header files to $(includedir)/liblibrary-version/library/. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:62 msgid "" "Install library binaries to $(libdir)/liblibrary-" "version.so.soname. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:67 msgid "" "Install pkg-config files to $(libdir)/pkgconfig/" "library-version.pc. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:72 msgid "" "Make configuration files forwards and backwards compatible, or install them " "to $(sysconfdir)/library-version/. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:78 msgid "" "Set GETTEXT_PACKAGE to library-version. ()" msgstr "" "Ορίστε το GETTEXT_PACKAGE στο library-" "version. ()" #. (itstool) path: item/p #: C/parallel-installability.page:83 msgid "" "Include a version number in all D-Bus interface names, service names and " "object paths. For example: org.domain.LibraryVersion.Interface, org.domain.LibraryVersion and /org/domain/LibraryVersion/. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:91 msgid "" "Install daemon binaries to $(libexecdir)/library-" "daemon-version. ()" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:96 msgid "" "Install utility binaries to $(bindir)/library-" "utility-version and install symbolic links to " "$(bindir)/library-utility. ()" msgstr "" #. (itstool) path: section/title #: C/parallel-installability.page:106 #, fuzzy msgid "Justification" msgstr "Στοίχιση" #. (itstool) path: section/p #: C/parallel-installability.page:108 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:117 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:123 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:131 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:138 msgid "" "The alternative, and equally valid, solution is for the library to never " "break API — the approach taken by libc." msgstr "" #. (itstool) path: section/title #: C/parallel-installability.page:145 msgid "Solution" msgstr "Λύση" #. (itstool) path: section/p #: C/parallel-installability.page:147 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:154 msgid "" "For example, say that library Foo traditionally installs these " "files:" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:159 C/parallel-installability.page:284 msgid "/usr/include/foo.h" msgstr "/usr/include/foo.h" #. (itstool) path: item/p #: C/parallel-installability.page:160 msgid "/usr/include/foo-utils.h" msgstr "/usr/include/foo-utils.h" #. (itstool) path: item/p #: C/parallel-installability.page:161 msgid "/usr/lib/libfoo.so" msgstr "/usr/lib/libfoo.so" #. (itstool) path: item/p #: C/parallel-installability.page:162 msgid "/usr/lib/pkgconfig/foo.pc" msgstr "/usr/lib/pkgconfig/foo.pc" #. (itstool) path: item/p #: C/parallel-installability.page:163 msgid "/usr/share/doc/foo/foo-manual.txt" msgstr "/usr/share/doc/foo/foo-manual.txt" #. (itstool) path: item/p #: C/parallel-installability.page:164 msgid "/usr/bin/foo-utility" msgstr "/usr/bin/foo-utility" #. (itstool) path: section/p #: C/parallel-installability.page:167 msgid "" "You might modify Foo version 4 to install these files instead:" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:172 C/parallel-installability.page:261 msgid "/usr/include/foo-4/foo/foo.h" msgstr "/usr/include/foo-4/foo/foo.h" #. (itstool) path: item/p #: C/parallel-installability.page:173 msgid "/usr/include/foo-4/foo/utils.h" msgstr "/usr/include/foo-4/foo/utils.h" #. (itstool) path: item/p #: C/parallel-installability.page:174 C/parallel-installability.page:338 msgid "/usr/lib/libfoo-4.so" msgstr "/usr/lib/libfoo-4.so" #. (itstool) path: item/p #: C/parallel-installability.page:175 C/parallel-installability.page:397 msgid "/usr/lib/pkgconfig/foo-4.pc" msgstr "/usr/lib/pkgconfig/foo-4.pc" #. (itstool) path: item/p #: C/parallel-installability.page:176 msgid "/usr/share/doc/foo-4/foo-manual.txt" msgstr "/usr/share/doc/foo-4/foo-manual.txt" #. (itstool) path: item/p #: C/parallel-installability.page:177 msgid "/usr/bin/foo-utility-4" msgstr "/usr/bin/foo-utility-4" #. (itstool) path: section/p #: C/parallel-installability.page:180 msgid "It could then be parallel installed with version 5:" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:184 C/parallel-installability.page:262 msgid "/usr/include/foo-5/foo/foo.h" msgstr "/usr/include/foo-5/foo/foo.h" #. (itstool) path: item/p #: C/parallel-installability.page:185 msgid "/usr/include/foo-5/foo/utils.h" msgstr "/usr/include/foo-5/foo/utils.h" #. (itstool) path: item/p #: C/parallel-installability.page:186 C/parallel-installability.page:339 msgid "/usr/lib/libfoo-5.so" msgstr "/usr/lib/libfoo-5.so" #. (itstool) path: item/p #: C/parallel-installability.page:187 C/parallel-installability.page:398 msgid "/usr/lib/pkgconfig/foo-5.pc" msgstr "/usr/lib/pkgconfig/foo-5.pc" #. (itstool) path: item/p #: C/parallel-installability.page:188 msgid "/usr/share/doc/foo-5/foo-manual.txt" msgstr "/usr/share/doc/foo-5/foo-manual.txt" #. (itstool) path: item/p #: C/parallel-installability.page:189 msgid "/usr/bin/foo-utility-5" msgstr "/usr/bin/foo-utility-5" #. (itstool) path: section/p #: C/parallel-installability.page:192 msgid "" "This is easily supported using pkg-config: foo-4.pc " "would add /usr/include/foo-4 to the include path and " "libfoo-4.so to the list of libraries to link; foo-5.pc would add /usr/include/foo-5 and libfoo-5.so." msgstr "" #. (itstool) path: section/title #: C/parallel-installability.page:204 msgid "Version Numbers" msgstr "Αριθμοί έκδοσης" #. (itstool) path: section/p #: C/parallel-installability.page:206 msgid "" "The version number that goes in filenames is an ABI/API version. It " "should not be the full version number of your package — just the part which " "signifies an API break. If using the standard major." "minor.micro scheme for project versioning, the " "API version is typically the major version number." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:214 msgid "" "Minor releases (typically where API is added but not changed or " "removed) and micro releases (typically bug fixes) do not affect API backwards compatibility so do not require " "moving all the files." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:221 msgid "" "The examples in the following sections assume that the API version and " "soname are exported from configure.ac using the following code:" msgstr "" #. (itstool) path: listing/title #: C/parallel-installability.page:227 #, fuzzy msgid "API Versioning in Autoconf" msgstr "Εκδόσεις" #. (itstool) path: listing/desc #: C/parallel-installability.page:228 msgid "" "Code to export the API version and soname from configure.ac" msgstr "" #. (itstool) path: listing/code #: C/parallel-installability.page:231 #, no-wrap msgid "" "# Before making a release, the LIBRARY_LT_VERSION string should be modified.\n" "# The string is of the form c:r:a. Follow these instructions sequentially:\n" "#\n" "# 1. If the library source code has changed at all since the last update,\n" "# then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).\n" "# 2. If any interfaces have been added, removed, or changed since the last update,\n" "# increment current, and set revision to 0.\n" "# 3. If any interfaces have been added since the last public release,\n" "# then increment age.\n" "# 4. If any interfaces have been removed or changed since the last public release,\n" "# then set age to 0.\n" "AC_SUBST([LIBRARY_LT_VERSION],[1:0:0])\n" "\n" "AC_SUBST([LIBRARY_API_VERSION],[4])" msgstr "" "# Before making a release, the LIBRARY_LT_VERSION string should be modified.\n" "# The string is of the form c:r:a. Follow these instructions sequentially:\n" "#\n" "# 1. If the library source code has changed at all since the last update,\n" "# then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).\n" "# 2. If any interfaces have been added, removed, or changed since the last update,\n" "# increment current, and set revision to 0.\n" "# 3. If any interfaces have been added since the last public release,\n" "# then increment age.\n" "# 4. If any interfaces have been removed or changed since the last public release,\n" "# then set age to 0.\n" "AC_SUBST([LIBRARY_LT_VERSION],[1:0:0])\n" "\n" "AC_SUBST([LIBRARY_API_VERSION],[4])" #. (itstool) path: section/title #: C/parallel-installability.page:249 msgid "C Header Files" msgstr "Αρχεία κεφαλίδων C" #. (itstool) path: section/p #: C/parallel-installability.page:251 msgid "" "Header files should always be installed in a versioned subdirectory that " "requires an -I flag to the C compiler. For example, if my header " "is foo.h, and applications do this:" msgstr "" #. (itstool) path: section/code #: C/parallel-installability.page:256 #, no-wrap msgid "#include <foo/foo.h>" msgstr "#include <foo/foo.h>" #. (itstool) path: section/p #: C/parallel-installability.page:257 #, fuzzy msgid "then I should install these files:" msgstr "Βρέθηκαν %i πακέτα προς εγκατάσταση:" #. (itstool) path: section/p #: C/parallel-installability.page:265 msgid "" "Applications should pass the flag -I/usr/include/foo-4 or -I/" "usr/include/foo-5 to the C compiler. Again, this is facilitated by " "using pkg-config." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:271 msgid "" "Note the extra foo/ subdirectory. This namespaces the #include to avoid file naming collisions with " "other libraries. For example, if two different libraries install headers " "called utils.h, which one gets included when you use #include <utils.h>?" msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:279 msgid "" "There’s some temptation to keep one of the header files outside of any " "subdirectory:" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:285 msgid "/usr/include/foo-5/foo.h" msgstr "/usr/include/foo-5/foo.h" #. (itstool) path: section/p #: C/parallel-installability.page:288 msgid "" "The problem there is that users are always accidentally getting the wrong " "header, since -I/usr/include 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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:296 msgid "" "Versioned header files can be installed from automake using the following " "code:" msgstr "" #. (itstool) path: listing/title #: C/parallel-installability.page:301 msgid "Header Files in Automake" msgstr "Κεφαλίδες στο Automake" #. (itstool) path: listing/desc #: C/parallel-installability.page:302 msgid "Code to install versioned header files from Makefile.am" msgstr "" #. (itstool) path: listing/code #: C/parallel-installability.page:305 #, no-wrap msgid "" "libraryincludedir = $(includedir)/liblibrary-@LIBRARY_API_VERSION@/library\n" "library_headers = \\\n" "\tliblibrary/example1.h \\\n" "\tliblibrary/example2.h \\\n" "\t$(NULL)\n" "\n" "# The following headers are private, and shouldn't be installed:\n" "private_headers = \\\n" "\tliblibrary/example-private.h \\\n" "\t$(NULL)\n" "# The main header simply #includes all other public headers:\n" "main_header = liblibrary/library.h\n" "public_headers = \\\n" "\t$(main_header) \\\n" "\t$(library_headers) \\\n" "\t$(NULL)\n" "\n" "libraryinclude_HEADERS = $(public_headers)" msgstr "" "libraryincludedir = $(includedir)/liblibrary-@LIBRARY_API_VERSION@/library\n" "library_headers = \\\n" "\tliblibrary/example1.h \\\n" "\tliblibrary/example2.h \\\n" "\t$(NULL)\n" "\n" "# The following headers are private, and shouldn't be installed:\n" "private_headers = \\\n" "\tliblibrary/example-private.h \\\n" "\t$(NULL)\n" "# The main header simply #includes all other public headers:\n" "main_header = liblibrary/library.h\n" "public_headers = \\\n" "\t$(main_header) \\\n" "\t$(library_headers) \\\n" "\t$(NULL)\n" "\n" "libraryinclude_HEADERS = $(public_headers)" #. (itstool) path: section/p #: C/parallel-installability.page:325 msgid "" "As well as correct versioning, all APIs in installed headers should be namespaced correctly." msgstr "" #. (itstool) path: section/title #: C/parallel-installability.page:332 msgid "Libraries" msgstr "Βιβλιοθήκες" #. (itstool) path: section/p #: C/parallel-installability.page:334 msgid "Library object files should have a versioned name. For example:" msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:342 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:347 msgid "" "Versioned libraries can be built and installed from automake using the " "following code:" msgstr "" #. (itstool) path: listing/title #: C/parallel-installability.page:352 msgid "Libraries in Automake" msgstr "Βιβλιοθήκες στο Automake" #. (itstool) path: listing/desc #: C/parallel-installability.page:353 msgid "" "Code to build and install versioned libraries from Makefile.am" msgstr "" #. (itstool) path: listing/code #: C/parallel-installability.page:357 #, no-wrap msgid "" "lib_LTLIBRARIES = liblibrary/liblibrary-@LIBRARY_API_VERSION@.la\n" "\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_SOURCES = \\\n" "\t$(private_headers) \\\n" "\t$(library_sources) \\\n" "\t$(NULL)\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_CPPFLAGS = …\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_CFLAGS = …\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_LIBADD = …\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_LDFLAGS = \\\n" "\t-version-info $(LIBRARY_LT_VERSION) \\\n" "\t$(AM_LDFLAGS) \\\n" "\t$(NULL)" msgstr "" "lib_LTLIBRARIES = liblibrary/liblibrary-@LIBRARY_API_VERSION@.la\n" "\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_SOURCES = \\\n" "\t$(private_headers) \\\n" "\t$(library_sources) \\\n" "\t$(NULL)\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_CPPFLAGS = …\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_CFLAGS = …\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_LIBADD = …\n" "liblibrary_liblibrary_@LIBRARY_API_VERSION@_la_LDFLAGS = \\\n" "\t-version-info $(LIBRARY_LT_VERSION) \\\n" "\t$(AM_LDFLAGS) \\\n" "\t$(NULL)" #. (itstool) path: section/title #: C/parallel-installability.page:373 #, fuzzy msgid "Library sonames" msgstr "Β_ιβλιοθήκη" #. (itstool) path: section/p #: C/parallel-installability.page:375 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:382 msgid "" "For this reason, sonames should be used, but in addition to " "versioned names for libraries. The two solutions address different problems." msgstr "" #. (itstool) path: section/title #: C/parallel-installability.page:391 msgid "pkg-config Files" msgstr "Αρχεία pkg-config" #. (itstool) path: section/p #: C/parallel-installability.page:393 msgid "pkg-config files should have a versioned name. For example:" msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:401 msgid "" "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 foo-4 to foo-5 (and doing any " "necessary API porting)." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:409 msgid "" "Versioned pkg-config files can be installed from autoconf and automake using " "the following code:" msgstr "" #. (itstool) path: listing/title #: C/parallel-installability.page:414 msgid "pkg-config Files in Autoconf and Automake" msgstr "" #. (itstool) path: listing/desc #: C/parallel-installability.page:415 msgid "" "Code to install versioned pkg-config files from configure.ac " "and Makefile.am" msgstr "" #. (itstool) path: listing/code #: C/parallel-installability.page:420 #, no-wrap msgid "" "AC_CONFIG_FILES([\n" "liblibrary/library-$LIBRARY_API_VERSION.pc:liblibrary/library.pc.in\n" "],[],\n" "[LIBRARY_API_VERSION='$LIBRARY_API_VERSION'])" msgstr "" "AC_CONFIG_FILES([\n" "liblibrary/library-$LIBRARY_API_VERSION.pc:liblibrary/library.pc.in\n" "],[],\n" "[LIBRARY_API_VERSION='$LIBRARY_API_VERSION'])" #. (itstool) path: listing/code #: C/parallel-installability.page:425 #, no-wrap msgid "" "# Note that the template file is called library.pc.in, but generates a\n" "# versioned .pc file using some magic in AC_CONFIG_FILES.\n" "pkgconfigdir = $(libdir)/pkgconfig\n" "pkgconfig_DATA = liblibrary/library-$(LIBRARY_API_VERSION).pc\n" "\n" "DISTCLEANFILES += $(pkgconfig_DATA)\n" "EXTRA_DIST += liblibrary/library.pc.in" msgstr "" "# Note that the template file is called library.pc.in, but generates a\n" "# versioned .pc file using some magic in AC_CONFIG_FILES.\n" "pkgconfigdir = $(libdir)/pkgconfig\n" "pkgconfig_DATA = liblibrary/library-$(LIBRARY_API_VERSION).pc\n" "\n" "DISTCLEANFILES += $(pkgconfig_DATA)\n" "EXTRA_DIST += liblibrary/library.pc.in" #. (itstool) path: section/title #: C/parallel-installability.page:436 msgid "Configuration Files" msgstr "Αρχεία ρυθμίσεων" #. (itstool) path: section/p #: C/parallel-installability.page:438 msgid "" "From a user standpoint, the best approach to configuration files is to keep " "the format both forward and backward " "compatible (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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:448 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/parallel-installability.page:455 msgid "Gettext Translations" msgstr "Μεταφράσεις Gettext" #. (itstool) path: section/p #: C/parallel-installability.page:457 msgid "" "If you use gettext for translations in combination with autoconf and " "automake, normally things are set up to install the translations to /" "usr/share/locale/lang/LC_MESSAGES/package. " "You’ll need to change package. The convention used in GNOME is to " "put this in configure.ac:" msgstr "" #. (itstool) path: section/code #: C/parallel-installability.page:465 #, no-wrap msgid "" "GETTEXT_PACKAGE=foo-4\n" "AC_SUBST([GETTEXT_PACKAGE])\n" "AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],[\"$GETTEXT_PACKAGE\"])" msgstr "" "GETTEXT_PACKAGE=foo-4\n" "AC_SUBST([GETTEXT_PACKAGE])\n" "AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],[\"$GETTEXT_PACKAGE\"])" #. (itstool) path: section/p #: C/parallel-installability.page:469 msgid "" "Then use GETTEXT_PACKAGE as the package name to pass to bindtextdomain(), textdomain(), and dgettext()." msgstr "" #. (itstool) path: section/title #: C/parallel-installability.page:482 msgid "D-Bus Interfaces" msgstr "Διεπαφές D-Bus" #. (itstool) path: section/p #: C/parallel-installability.page:484 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:492 msgid "" "For example, for a service org.example.Foo exposing interfaces " "A and B on objects Controller and " "Client, versions 4 and 5 of the D-Bus API would look like this:" msgstr "" #. (itstool) path: list/title #: C/parallel-installability.page:499 msgid "Service Names" msgstr "Όνομα υπηρεσίας" #. (itstool) path: item/p #: C/parallel-installability.page:500 msgid "org.example.Foo4" msgstr "org.example.Foo4" #. (itstool) path: item/p #: C/parallel-installability.page:501 msgid "org.example.Foo5" msgstr "org.example.Foo5" #. (itstool) path: list/title #: C/parallel-installability.page:504 msgid "Interface Names" msgstr "Όνομα διεπαφών" #. (itstool) path: item/p #: C/parallel-installability.page:505 msgid "org.example.Foo4.InterfaceA" msgstr "org.example.Foo4.InterfaceA" #. (itstool) path: item/p #: C/parallel-installability.page:506 msgid "org.example.Foo4.InterfaceB" msgstr "org.example.Foo4.InterfaceB" #. (itstool) path: item/p #: C/parallel-installability.page:507 msgid "org.example.Foo5.InterfaceA" msgstr "org.example.Foo5.InterfaceA" #. (itstool) path: item/p #: C/parallel-installability.page:508 msgid "org.example.Foo5.InterfaceB" msgstr "org.example.Foo5.InterfaceB" #. (itstool) path: list/title #: C/parallel-installability.page:511 msgid "Object Paths" msgstr "Διαδρομές αντικειμένων" #. (itstool) path: item/p #: C/parallel-installability.page:512 msgid "/org/example/Foo4/Controller" msgstr "/org/example/Foo4/Controller" #. (itstool) path: item/p #: C/parallel-installability.page:513 msgid "/org/example/Foo4/Client" msgstr "/org/example/Foo4/Client" #. (itstool) path: item/p #: C/parallel-installability.page:514 msgid "/org/example/Foo5/Controller" msgstr "/org/example/Foo5/Controller" #. (itstool) path: item/p #: C/parallel-installability.page:515 msgid "/org/example/Foo5/Client" msgstr "/org/example/Foo5/Client" #. (itstool) path: section/title #: C/parallel-installability.page:527 #, fuzzy msgid "Programs, Daemons and Utilities" msgstr "Δομές δεδομένων και βοηθήματα για προγράμματα C" #. (itstool) path: section/p #: C/parallel-installability.page:529 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:536 msgid "Given a daemon and utility program:" msgstr "" #. (itstool) path: item/p #: C/parallel-installability.page:540 msgid "/usr/libexec/foo-daemon" msgstr "/usr/libexec/foo-daemon" #. (itstool) path: item/p #: C/parallel-installability.page:541 msgid "/usr/bin/foo-lookup-utility" msgstr "/usr/bin/foo-lookup-utility" #. (itstool) path: section/p #: C/parallel-installability.page:543 #, fuzzy msgid "these should be versioned as:" msgstr "_Χωρίς έκδοση" #. (itstool) path: item/p #: C/parallel-installability.page:547 msgid "/usr/libexec/foo-daemon-4" msgstr "/usr/libexec/foo-daemon-4" #. (itstool) path: item/p #: C/parallel-installability.page:548 msgid "/usr/bin/foo-lookup-utility-4" msgstr "" #. (itstool) path: section/p #: C/parallel-installability.page:551 msgid "" "You may want to install a symbolic link from /usr/bin/foo-lookup-" "utility to the recommended versioned copy of the utility, to make it " "more convenient for users to use." msgstr "" #. (itstool) path: info/desc #: C/preconditions.page:18 msgid "Contract programming with checks on function input and output" msgstr "" #. (itstool) path: page/title #. (itstool) path: section/title #: C/preconditions.page:21 C/preconditions.page:24 msgid "Pre- and Post-Conditions" msgstr "" #. (itstool) path: section/p #: C/preconditions.page:26 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/preconditions.page:33 msgid "" "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:" msgstr "" #. (itstool) path: item/title #: C/preconditions.page:40 msgid "Assertions" msgstr "" #. (itstool) path: item/p #: C/preconditions.page:41 msgid "Check for programmer errors and abort the program on failure." msgstr "" #. (itstool) path: item/title #: C/preconditions.page:46 msgid "Validation" msgstr "" #. (itstool) path: item/p #: C/preconditions.page:47 msgid "Check for invalid input and return an error gracefully on failure." msgstr "" #. (itstool) path: section/p #: C/preconditions.page:53 msgid "" "Validation is a complex topic, and is handled using GErrors. 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 NULL is passed to a parameter " "which is documented as requiring a non-NULL 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 " "NULL when it is not documented to, or not setting a GError " "output when it fails." msgstr "" #. (itstool) path: section/p #: C/preconditions.page:67 msgid "" "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 introspection annotations, such as (nullable)." msgstr "" #. (itstool) path: section/p #: C/preconditions.page:76 msgid "" "Pre- and post-condition assertions are implemented using g_return_if_fail() and g_return_val_if_fail()." msgstr "" #. (itstool) path: section/p #: C/preconditions.page:83 msgid "" "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 " "NULL). The post-conditions should check the return value and " "any output parameters at the end of the function — this requires a single " "return statement and use of goto to merge other " "control paths into it. See for an example." msgstr "" #. (itstool) path: info/desc #: C/threading.page:18 msgid "Moving computation out of the main thread into worker threads" msgstr "" #. (itstool) path: page/title #: C/threading.page:21 msgid "Threading" msgstr "Νηματοποίηση" #. (itstool) path: item/p #: C/threading.page:27 msgid "" "Do not use threads if at all possible. ()" msgstr "" #. (itstool) path: item/p #: C/threading.page:31 msgid "" "If threads have to be used, use GTask or GThreadPool and isolate the threaded code as much as possible. ()" msgstr "" #. (itstool) path: item/p #: C/threading.page:37 msgid "" "Use g_thread_join() to avoid leaking thread resources if using " "GThread manually. ()" msgstr "" #. (itstool) path: item/p #: C/threading.page:42 msgid "" "Be careful about the GMainContext which code is executed in if " "using threads. Executing code in the wrong context can cause race " "conditions, or block the main loop. ()" msgstr "" #. (itstool) path: section/title #: C/threading.page:52 msgid "When to Use Threading" msgstr "Πότε να χρησιμοποιήσετε νηματοποίηση" #. (itstool) path: section/p #: C/threading.page:54 msgid "" "When writing projects using GLib, the default approach should be to never use threads. Instead, make proper use of the " "GLib main context which, through the use " "of asynchronous operations, 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." msgstr "" #. (itstool) path: section/p #: C/threading.page:64 msgid "" "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 poll() 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 GAsyncResult style of " "GLib asynchronous function, running the blocking operation in a worker " "thread." msgstr "" #. (itstool) path: example/code #: C/threading.page:82 #, no-wrap msgid "" "\n" "int\n" "some_blocking_function (void *param1,\n" " void *param2);\n" msgstr "" "\n" "int\n" "some_blocking_function (void *param1,\n" " void *param2);\n" #. (itstool) path: example/p #: C/threading.page:87 #, fuzzy msgid "Should be wrapped as:" msgstr "Αναδιπλωμένο" #. (itstool) path: example/code #: C/threading.page:90 #, no-wrap msgid "" "\n" "void\n" "some_blocking_function_async (void *param1,\n" " void *param2,\n" " GCancellable *cancellable,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data);\n" "int\n" "some_blocking_function_finish (GAsyncResult *result,\n" " GError **error);\n" msgstr "" "\n" "void\n" "some_blocking_function_async (void *param1,\n" " void *param2,\n" " GCancellable *cancellable,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data);\n" "int\n" "some_blocking_function_finish (GAsyncResult *result,\n" " GError **error);\n" #. (itstool) path: example/p #: C/threading.page:102 #, fuzzy msgid "With an implementation something like:" msgstr "Αυτό το κάνει να μοιάζει σαν αυτό:" #. (itstool) path: example/code #: C/threading.page:105 #, no-wrap msgid "" "/* Closure for the call’s parameters. */\n" "typedef struct {\n" " void *param1;\n" " void *param2;\n" "} SomeBlockingFunctionData;\n" "\n" "static void\n" "some_blocking_function_data_free (SomeBlockingFunctionData *data)\n" "{\n" " free_param (data->param1);\n" " free_param (data->param2);\n" "\n" " g_free (data);\n" "}\n" "\n" "static void\n" "some_blocking_function_thread_cb (GTask *task,\n" " gpointer source_object,\n" " gpointer task_data,\n" " GCancellable *cancellable)\n" "{\n" " SomeBlockingFunctionData *data = task_data;\n" " int retval;\n" "\n" " /* Handle cancellation. */\n" " if (g_task_return_error_if_cancelled (task))\n" " {\n" " return;\n" " }\n" "\n" " /* Run the blocking function. */\n" " retval = some_blocking_function (data->param1, data->param2);\n" " g_task_return_int (task, retval);\n" "}\n" "\n" "void\n" "some_blocking_function_async (void *param1,\n" " void *param2,\n" " GCancellable *cancellable,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data)\n" "{\n" " GTask *task = NULL; /* owned */\n" " SomeBlockingFunctionData *data = NULL; /* owned */\n" "\n" " g_return_if_fail (validate_param (param1));\n" " g_return_if_fail (validate_param (param2));\n" " g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));\n" "\n" " task = g_task_new (NULL, cancellable, callback, user_data);\n" " g_task_set_source_tag (task, some_blocking_function_async);\n" "\n" " /* Cancellation should be handled manually using mechanisms specific to\n" " * some_blocking_function(). */\n" " g_task_set_return_on_cancel (task, FALSE);\n" "\n" " /* Set up a closure containing the call’s parameters. Copy them to avoid\n" " * locking issues between the calling thread and the worker thread. */\n" " data = g_new0 (SomeBlockingFunctionData, 1);\n" " data->param1 = copy_param (param1);\n" " data->param2 = copy_param (param2);\n" "\n" " g_task_set_task_data (task, data, some_blocking_function_data_free);\n" "\n" " /* Run the task in a worker thread and return immediately while that continues\n" " * in the background. When it’s done it will call @callback in the current\n" " * thread default main context. */\n" " g_task_run_in_thread (task, some_blocking_function_thread_cb);\n" "\n" " g_object_unref (task);\n" "}\n" "\n" "int\n" "some_blocking_function_finish (GAsyncResult *result,\n" " GError **error)\n" "{\n" " g_return_val_if_fail (g_task_is_valid (result,\n" " some_blocking_function_async), -1);\n" " g_return_val_if_fail (error == NULL || *error == NULL, -1);\n" "\n" " return g_task_propagate_int (G_TASK (result), error);\n" "}" msgstr "" "/* Closure for the call’s parameters. */\n" "typedef struct {\n" " void *param1;\n" " void *param2;\n" "} SomeBlockingFunctionData;\n" "\n" "static void\n" "some_blocking_function_data_free (SomeBlockingFunctionData *data)\n" "{\n" " free_param (data->param1);\n" " free_param (data->param2);\n" "\n" " g_free (data);\n" "}\n" "\n" "static void\n" "some_blocking_function_thread_cb (GTask *task,\n" " gpointer source_object,\n" " gpointer task_data,\n" " GCancellable *cancellable)\n" "{\n" " SomeBlockingFunctionData *data = task_data;\n" " int retval;\n" "\n" " /* Handle cancellation. */\n" " if (g_task_return_error_if_cancelled (task))\n" " {\n" " return;\n" " }\n" "\n" " /* Run the blocking function. */\n" " retval = some_blocking_function (data->param1, data->param2);\n" " g_task_return_int (task, retval);\n" "}\n" "\n" "void\n" "some_blocking_function_async (void *param1,\n" " void *param2,\n" " GCancellable *cancellable,\n" " GAsyncReadyCallback callback,\n" " gpointer user_data)\n" "{\n" " GTask *task = NULL; /* owned */\n" " SomeBlockingFunctionData *data = NULL; /* owned */\n" "\n" " g_return_if_fail (validate_param (param1));\n" " g_return_if_fail (validate_param (param2));\n" " g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));\n" "\n" " task = g_task_new (NULL, cancellable, callback, user_data);\n" " g_task_set_source_tag (task, some_blocking_function_async);\n" "\n" " /* Cancellation should be handled manually using mechanisms specific to\n" " * some_blocking_function(). */\n" " g_task_set_return_on_cancel (task, FALSE);\n" "\n" " /* Set up a closure containing the call’s parameters. Copy them to avoid\n" " * locking issues between the calling thread and the worker thread. */\n" " data = g_new0 (SomeBlockingFunctionData, 1);\n" " data->param1 = copy_param (param1);\n" " data->param2 = copy_param (param2);\n" "\n" " g_task_set_task_data (task, data, some_blocking_function_data_free);\n" "\n" " /* Run the task in a worker thread and return immediately while that continues\n" " * in the background. When it’s done it will call @callback in the current\n" " * thread default main context. */\n" " g_task_run_in_thread (task, some_blocking_function_thread_cb);\n" "\n" " g_object_unref (task);\n" "}\n" "\n" "int\n" "some_blocking_function_finish (GAsyncResult *result,\n" " GError **error)\n" "{\n" " g_return_val_if_fail (g_task_is_valid (result,\n" " some_blocking_function_async), -1);\n" " g_return_val_if_fail (error == NULL || *error == NULL, -1);\n" "\n" " return g_task_propagate_int (G_TASK (result), error);\n" "}" #. (itstool) path: example/p #: C/threading.page:187 msgid "" "See the GAsyncResult documentation for more details. A simple " "way to implement the worker thread is to use GTask and g_task_run_in_thread(). (See also: .)" msgstr "" #. (itstool) path: section/title #: C/threading.page:200 msgid "Using Threading" msgstr "Χρήση νηματοποίησης" #. (itstool) path: section/p #: C/threading.page:202 msgid "" "If GTask 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." msgstr "" #. (itstool) path: section/p #: C/threading.page:210 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/threading.page:222 msgid "" "Use GThreadPool instead of manually creating GThreads if possible. GThreadPool " "supports a work queue, limits on the number of spawned threads, and " "automatically joins finished threads so they are not leaked." msgstr "" #. (itstool) path: item/p #: C/threading.page:232 msgid "" "If it is not possible to use a GThreadPool (which is rarely the " "case):" msgstr "" #. (itstool) path: item/p #: C/threading.page:239 msgid "" "Use g_thread_try_new() to spawn threads, " "instead of g_thread_new(), so errors due to the " "system running out of threads can be handled gracefully rather than " "unconditionally aborting the program." msgstr "" #. (itstool) path: item/p #: C/threading.page:248 msgid "" "Explicitly join threads using g_thread_join() " "to avoid leaking the thread resources." msgstr "" #. (itstool) path: item/p #: C/threading.page:257 msgid "" "Use message passing to transfer data between threads, rather than manual " "locking with mutexes. GThreadPool explicitly supports this with " "g_thread_pool_push()." msgstr "" #. (itstool) path: item/p #: C/threading.page:265 #, fuzzy msgid "If mutexes must be used:" msgstr "Η επιλογή %s πρέπει να χρησιμοποιείται μόνη της.\n" #. (itstool) path: item/p #: C/threading.page:271 msgid "" "Isolate threading code as much as possible, keeping mutexes private within " "classes, and tightly bound to very specific class members." msgstr "" #. (itstool) path: item/p #: C/threading.page:278 msgid "" "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 only be " "accessed with that mutex held." msgstr "" #. (itstool) path: item/p #: C/threading.page:288 msgid "" "Be careful about interactions between main contexts and threads. For " "example, g_timeout_add_seconds() adds a timeout to be executed in the global default main " "context, which is being run in the main thread, not necessarily 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: .)" msgstr "" #. (itstool) path: section/title #: C/threading.page:304 msgid "Debugging" msgstr "Αποσφαλμάτωση" #. (itstool) path: section/p #: C/threading.page:306 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/threading.page:312 msgid "" "However, if a threading issue does arise, Valgrind’s drd and helgrind tools are useful." msgstr "" #. (itstool) path: info/desc #: C/tooling.page:17 msgid "Using the right tool for various tasks" msgstr "" #. (itstool) path: page/title #: C/tooling.page:20 msgid "Tooling" msgstr "" #. (itstool) path: page/p #: C/tooling.page:22 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/tooling.page:31 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/tooling.page:39 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/tooling.page:48 msgid "" "Compile frequently with a second compiler. ()" msgstr "" #. (itstool) path: item/p #: C/tooling.page:52 msgid "" "Enable a large selection of compiler warnings and make them fatal. ()" msgstr "" #. (itstool) path: item/p #: C/tooling.page:56 msgid "Use GDB to debug and step through code. ()" msgstr "" #. (itstool) path: item/p #: C/tooling.page:59 msgid "" "Use Valgrind to analyze memory usage, memory errors, cache and CPU " "performance and threading errors. ()" msgstr "" #. (itstool) path: item/p #: C/tooling.page:63 msgid "" "Use gcov and lcov to analyze unit test coverage. ()" msgstr "" #. (itstool) path: item/p #: C/tooling.page:67 msgid "" "Use compiler sanitizers to analyze memory, thread and undefined behavior " "problems. ()" msgstr "" #. (itstool) path: item/p #: C/tooling.page:71 msgid "" "Submit to Coverity as a cronjob and eliminate static analysis errors as they " "appear. ()" msgstr "" #. (itstool) path: item/p #: C/tooling.page:75 msgid "" "Use Clang static analyzer and Tartan regularly to eliminate statically " "analysable errors locally. ()" msgstr "" #. (itstool) path: section/title #: C/tooling.page:83 msgid "GCC and Clang" msgstr "GCC και Clang" #. (itstool) path: section/p #: C/tooling.page:85 msgid "" "GCC is the " "standard C compiler for Linux. An alternative exists in the form of Clang, 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 ." msgstr "" #. (itstool) path: section/p #: C/tooling.page:97 msgid "" "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 -Werror 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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:112 msgid "" "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 AX_COMPILER_FLAGS macro exists." msgstr "" #. (itstool) path: section/p #: C/tooling.page:121 msgid "" "AX_COMPILER_FLAGS 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 AX_COMPILER_FLAGS to " "configure.ac. If you are using in-tree copies of autoconf-" "archive macros, copy " "ax_compiler_flags.m4 to the m4/ directory " "of your project. Note that it depends on the following autoconf-archive " "macros which are GPL-licenced 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:" msgstr "" #. (itstool) path: item/p #: C/tooling.page:136 msgid "ax_append_compile_flags.m4" msgstr "ax_append_compile_flags.m4" #. (itstool) path: item/p #: C/tooling.page:137 msgid "ax_append_flag.m4" msgstr "ax_append_flag.m4" #. (itstool) path: item/p #: C/tooling.page:138 msgid "ax_check_compile_flag.m4" msgstr "ax_check_compile_flag.m4" #. (itstool) path: item/p #: C/tooling.page:139 msgid "ax_require_defined.m4" msgstr "ax_require_defined.m4" #. (itstool) path: section/p #: C/tooling.page:142 msgid "" "AX_COMPILER_FLAGS supports disabling -Werror 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 -Werror enabled." msgstr "" #. (itstool) path: section/p #: C/tooling.page:151 msgid "" "Release builds can be detected using the AX_IS_RELEASE macro, the result of which can be passed directly to " "AX_COMPILER_FLAGS:" msgstr "" #. (itstool) path: section/code #: C/tooling.page:157 #, no-wrap msgid "" "AX_IS_RELEASE([git])\n" "AX_COMPILER_FLAGS([WARN_CFLAGS],[WARN_LDFLAGS],[$ax_is_release])" msgstr "" "AX_IS_RELEASE([git])\n" "AX_COMPILER_FLAGS([WARN_CFLAGS],[WARN_LDFLAGS],[$ax_is_release])" #. (itstool) path: section/p #: C/tooling.page:160 msgid "" "The choice of release stability policy (the first argument to " "AX_IS_RELEASE) should be made per project, taking the project’s " "versioning stability into account." msgstr "" #. (itstool) path: section/title #: C/tooling.page:169 msgid "GDB" msgstr "GDB" #. (itstool) path: section/p #: C/tooling.page:171 msgid "" "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 here." msgstr "" #. (itstool) path: section/p #: C/tooling.page:179 msgid "" "To run GDB on a program from within the source tree, use: libtool exec " "gdb --args ./program-name --some --arguments --here" msgstr "" #. (itstool) path: section/p #: C/tooling.page:184 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:190 msgid "" "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 reference " "count debugging), but sometimes simply using " "g_debug() to output a debug message is simpler." msgstr "" #. (itstool) path: section/title #: C/tooling.page:202 msgid "Valgrind" msgstr "Valgrind" #. (itstool) path: section/p #: C/tooling.page:204 msgid "" "Valgrind is a suite of tools for instrumenting and profiling programs. Its " "most famous tool is memcheck, but it has " "several other powerful and useful tools too. They are covered separately in " "the sections below." msgstr "" #. (itstool) path: section/p #: C/tooling.page:211 msgid "" "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 make check, this will " "cause the checks to succeed if Valgrind finds no problems, and fail " "otherwise. However, running make check under Valgrind is not " "trivial to do on the command line. A macro, AX_VALGRIND_CHECK can be used which adds a new make check-valgrind " "target to automate this. To use it:" msgstr "" #. (itstool) path: item/p #: C/tooling.page:224 msgid "" "Copy ax_valgrind_check.m4 to the m4/ directory of your project." msgstr "" #. (itstool) path: item/p #: C/tooling.page:230 msgid "Add AX_VALGRIND_CHECK to configure.ac." msgstr "" "Προσθέστε το AX_VALGRIND_CHECK στο configure.ac." #. (itstool) path: item/p #: C/tooling.page:233 #, fuzzy #| msgid "Add AX_VALGRIND_CHECK to configure.ac." msgid "" "Add @VALGRIND_CHECK_RULES@ to the Makefile.am in " "each directory which contains unit tests." msgstr "" "Προσθέστε το AX_VALGRIND_CHECK στο configure.ac." #. (itstool) path: section/p #: C/tooling.page:239 msgid "" "When make check-valgrind is run, it will save its results in " "test-suite-*.log, one log file per tool. Note that you will " "need to run it from the directory containing the unit tests." msgstr "" #. (itstool) path: section/p #: C/tooling.page:251 msgid "" "Valgrind has a way to suppress false positives, by using " "suppression files. 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 memcheck and helgrind and drd 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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:264 msgid "" "Suppression files are supported by the AX_VALGRIND_CHECK macro:" msgstr "" #. (itstool) path: section/code #: C/tooling.page:268 #, no-wrap msgid "" "@VALGRIND_CHECK_RULES@\n" "VALGRIND_SUPPRESSIONS_FILES = my-project.supp glib.supp\n" "EXTRA_DIST = $(VALGRIND_SUPPRESSIONS_FILES)" msgstr "" "@VALGRIND_CHECK_RULES@\n" "VALGRIND_SUPPRESSIONS_FILES = my-project.supp glib.supp\n" "EXTRA_DIST = $(VALGRIND_SUPPRESSIONS_FILES)" #. (itstool) path: section/title #: C/tooling.page:273 msgid "memcheck" msgstr "memcheck" #. (itstool) path: section/p #: C/tooling.page:275 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:286 msgid "To run memcheck manually on an installed program, use:" msgstr "" #. (itstool) path: section/p #: C/tooling.page:289 msgid "" "valgrind --tool=memcheck --leak-check=full my-program-name" msgstr "" "valgrind --tool=memcheck --leak-check=full my-program-name" #. (itstool) path: section/p #: C/tooling.page:293 msgid "" "Or, if running your program from the source directory, use the following to " "avoid running leak checking on the libtool helper scripts:" msgstr "" #. (itstool) path: section/p #: C/tooling.page:297 msgid "" "libtool exec valgrind --tool=memcheck --leak-check=full ./my-" "program-name" msgstr "" "libtool exec valgrind --tool=memcheck --leak-check=full ./my-" "program-name" #. (itstool) path: section/p #: C/tooling.page:301 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:307 msgid "" "A full tutorial on using memcheck is here." msgstr "" #. (itstool) path: section/title #: C/tooling.page:314 msgid "cachegrind and KCacheGrind" msgstr "cachegrind και KCacheGrind" #. (itstool) path: section/p #: C/tooling.page:316 msgid "" "cachegrind is a cache performance profiler which can also measure " "instruction execution, and hence is very useful for profiling general " "performance of a program. KCacheGrind is a useful UI for it which allows " "visualization and exploration of the profiling data, and the two tools " "should rarely be used separately." msgstr "" #. (itstool) path: section/p #: C/tooling.page:326 msgid "" "cachegrind works by simulating the processor’s memory hierarchy, so there " "are situations where it is not perfectly accurate. " "However, its results are always representative enough to be very useful in " "debugging performance hotspots." msgstr "" #. (itstool) path: section/p #: C/tooling.page:335 msgid "" "A full tutorial on using cachegrind is here." msgstr "" #. (itstool) path: section/title #: C/tooling.page:342 msgid "helgrind and drd" msgstr "helgrind και drd" #. (itstool) path: section/p #: C/tooling.page:344 msgid "" "helgrind and drd are threading error detectors, checking for race conditions " "in memory accesses, and abuses of the POSIX pthreads API. " "They are similar tools, but are implemented using different techniques, so " "both should be used." msgstr "" #. (itstool) path: section/p #: C/tooling.page:352 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:362 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:369 msgid "" "Full tutorials on using helgrind and drd are here and here." msgstr "" #. (itstool) path: section/title #: C/tooling.page:378 msgid "sgcheck" msgstr "sgcheck" #. (itstool) path: section/p #: C/tooling.page:380 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:387 msgid "" "As it is experimental, sgcheck must be run by passing --tool=exp-" "sgcheck to Valgrind, rather than --tool=sgcheck." msgstr "" #. (itstool) path: section/p #: C/tooling.page:393 msgid "" "A full tutorial on using sgcheck is here." msgstr "" #. (itstool) path: section/title #: C/tooling.page:401 msgid "gcov and lcov" msgstr "gcov και lcov" #. (itstool) path: section/p #: C/tooling.page:403 msgid "" "gcov 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 " ".gcda and .gcno profiling output files. These " "files can be analyzed by the lcov tool, which generates visual " "reports of code coverage at runtime, highlighting lines of code in the " "project which are run more than others." msgstr "" #. (itstool) path: section/p #: C/tooling.page:413 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/tooling.page:424 msgid "" "lcov supports branch coverage measurement, " "so is not suitable for demonstrating coverage of safety critical code. It is " "perfectly suitable for non-safety critical code." msgstr "" #. (itstool) path: section/p #: C/tooling.page:432 msgid "" "As code coverage has to be enabled at both compile time and run time, a " "macro is provided to make things simpler. The " "AX_CODE_COVERAGE macro adds a make check-code-" "coverage target to the build system, which runs the unit tests with " "code coverage enabled, and generates a report using lcov." msgstr "" #. (itstool) path: section/p #: C/tooling.page:442 msgid "To add AX_CODE_COVERAGE support to a project:" msgstr "" #. (itstool) path: item/p #: C/tooling.page:446 msgid "" "Copy ax_code_coverage.m4 to the m4/ directory of your project." msgstr "" #. (itstool) path: item/p #: C/tooling.page:452 msgid "Add AX_CODE_COVERAGE to configure.ac." msgstr "Προσθέστε AX_CODE_COVERAGE στο configure.ac." #. (itstool) path: item/p #: C/tooling.page:455 msgid "" "Add @CODE_COVERAGE_RULES to the top-level Makefile.am." msgstr "" #. (itstool) path: item/p #: C/tooling.page:459 msgid "" "Add $(CODE_COVERAGE_CFLAGS) to the automake *_CFLAGS variable for each target you want coverage for, for " "example for all libraries but no unit test code. Do the same for " "$(CODE_COVERAGE_LDFLAGS) and *_LDFLAGS." msgstr "" #. (itstool) path: section/p #: C/tooling.page:468 msgid "" "Documentation on using gcov and lcov is here." msgstr "" #. (itstool) path: section/title #: C/tooling.page:475 msgid "Address, Thread and Undefined Behavior Sanitizers" msgstr "" #. (itstool) path: section/p #: C/tooling.page:477 msgid "" "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 Valgrind. They are still young, " "so have little integration with other tooling." msgstr "" #. (itstool) path: section/p #: C/tooling.page:487 msgid "" "All sanitizers are available for both GCC and Clang, accepting the same set " "of compiler options." msgstr "" #. (itstool) path: section/title #: C/tooling.page:500 #, fuzzy msgid "Address Sanitizer" msgstr "_Σε αυτή τη διεύθυνση" #. (itstool) path: section/p #: C/tooling.page:502 msgid "" "The address " "sanitizer (‘asan’) detects use-after-free and buffer overflow bugs in " "C and C++ programs. A full tutorial on using asan is available for Clang " "— the same instructions should work for GCC." msgstr "" #. (itstool) path: section/title #: C/tooling.page:512 #, fuzzy msgid "Thread Sanitizer" msgstr "Νήμα" #. (itstool) path: section/p #: C/tooling.page:514 msgid "" "The thread " "sanitizer (‘tsan’) detects data races on memory locations, plus a " "variety of invalid uses of POSIX threading APIs. A full tutorial on using " "tsan is available for Clang — the same instructions should work for GCC." msgstr "" #. (itstool) path: section/title #: C/tooling.page:525 #, fuzzy msgid "Undefined Behavior Sanitizer" msgstr "_Συμπεριφορά" #. (itstool) path: section/p #: C/tooling.page:527 msgid "" "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 available " "for Clang — the same instructions should work for GCC." msgstr "" #. (itstool) path: section/title #: C/tooling.page:538 msgid "Coverity" msgstr "" #. (itstool) path: section/p #: C/tooling.page:540 msgid "" "Coverity 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 sign " "up. Analysis is performed 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)." msgstr "" #. (itstool) path: section/p #: C/tooling.page:553 msgid "" "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 compiler " "warnings can be taken: eliminate all the static analysis warnings, " "then eliminate new ones as they are detected." msgstr "" #. (itstool) path: section/p #: C/tooling.page:566 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/tooling.page:574 #, fuzzy msgid "Clang Static Analyzer" msgstr "Clang" #. (itstool) path: section/p #: C/tooling.page:576 msgid "" "One tool which can be used to perform static analysis locally is the Clang static analyzer, which " "is a tool co-developed with the Clang " "compiler. 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)." msgstr "" #. (itstool) path: section/p #: C/tooling.page:585 msgid "" "Clang produces some false positives, and there is no easy way to ignore " "them. The recommended thing to do is to file a bug report against the static " "analyzer, so that the false positive can be fixed in future." msgstr "" #. (itstool) path: section/p #: C/tooling.page:593 msgid "" "A full tutorial on using Clang is here." msgstr "" #. (itstool) path: section/title #: C/tooling.page:599 msgid "Tartan" msgstr "" #. (itstool) path: section/p #: C/tooling.page:601 msgid "" "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 Tartan, which extends Clang to support checks against some of the common GLib " "APIs." msgstr "" #. (itstool) path: section/p #: C/tooling.page:612 msgid "" "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 report any problems with " "Tartan." msgstr "" #. (itstool) path: section/p #: C/tooling.page:621 msgid "" "A full tutorial on enabling Tartan for use with the Clang static analyzer is " " " "here. If set up correctly, the output from Tartan will be mixed " "together with the normal static analyzer output." msgstr "" #. (itstool) path: info/desc #: C/unit-testing.page:17 msgid "Designing software to be tested and writing unit tests for it" msgstr "" #. (itstool) path: page/title #: C/unit-testing.page:20 #, fuzzy msgid "Unit Testing" msgstr "Μονάδα" #. (itstool) path: synopsis/p #: C/unit-testing.page:25 msgid "" "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." msgstr "" #. (itstool) path: synopsis/p #: C/unit-testing.page:31 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:38 msgid "" "Write unit tests to be as small as possible, but no smaller. ()" msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:42 msgid "" "Use code coverage tools to write tests to get high code coverage. ()" msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:46 msgid "" "Run all unit tests under Valgrind to check for leaks and other problems. " "()" msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:50 msgid "" "Use appropriate tools to automatically generate unit tests where possible. " "()" msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:54 msgid "" "Design code to be testable from the beginning. ()" msgstr "" #. (itstool) path: section/title #: C/unit-testing.page:62 #, fuzzy msgid "Writing Unit Tests" msgstr "Κατά εξετάσεις" #. (itstool) path: section/p #: C/unit-testing.page:64 msgid "" "Unit tests should be written in conjunction with looking at code coverage information gained from running the " "tests. 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." msgstr "" #. (itstool) path: section/p #: C/unit-testing.page:79 msgid "" "Like git commits, 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." msgstr "" #. (itstool) path: section/p #: C/unit-testing.page:90 msgid "" "GLib has support for unit testing with its GTest framework, 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 -p argument: ./test-suite-name -p /path/" "to/test/group." msgstr "" #. (itstool) path: section/title #: C/unit-testing.page:101 #, fuzzy msgid "Installed Tests" msgstr "Κατά εξετάσεις" #. (itstool) path: section/p #: C/unit-testing.page:103 msgid "" "All unit tests should be installed system-wide, following the installed-" "tests standard." msgstr "" #. (itstool) path: section/p #: C/unit-testing.page:109 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/unit-testing.page:116 msgid "" "To add support for installed-tests, add the following to configure.ac:" msgstr "" #. (itstool) path: section/code #: C/unit-testing.page:120 #, no-wrap msgid "" "# Installed tests\n" "AC_ARG_ENABLE([modular_tests],\n" " AS_HELP_STRING([--disable-modular-tests],\n" " [Disable build of test programs (default: no)]),,\n" " [enable_modular_tests=yes])\n" "AC_ARG_ENABLE([installed_tests],\n" " AS_HELP_STRING([--enable-installed-tests],\n" " [Install test programs (default: no)]),,\n" " [enable_installed_tests=no])\n" "AM_CONDITIONAL([BUILD_MODULAR_TESTS],\n" " [test \"$enable_modular_tests\" = \"yes\" ||\n" " test \"$enable_installed_tests\" = \"yes\"])\n" "AM_CONDITIONAL([BUILDOPT_INSTALL_TESTS],[test \"$enable_installed_tests\" = \"yes\"])" msgstr "" "# Installed tests\n" "AC_ARG_ENABLE([modular_tests],\n" " AS_HELP_STRING([--disable-modular-tests],\n" " [Disable build of test programs (default: no)]),,\n" " [enable_modular_tests=yes])\n" "AC_ARG_ENABLE([installed_tests],\n" " AS_HELP_STRING([--enable-installed-tests],\n" " [Install test programs (default: no)]),,\n" " [enable_installed_tests=no])\n" "AM_CONDITIONAL([BUILD_MODULAR_TESTS],\n" " [test \"$enable_modular_tests\" = \"yes\" ||\n" " test \"$enable_installed_tests\" = \"yes\"])\n" "AM_CONDITIONAL([BUILDOPT_INSTALL_TESTS],[test \"$enable_installed_tests\" = \"yes\"])" #. (itstool) path: section/p #: C/unit-testing.page:134 #, fuzzy msgid "Then in tests/Makefile.am:" msgstr "Προσθέστε την παρακάτω γραμμή στο Makefile.am:" #. (itstool) path: section/code #: C/unit-testing.page:137 #, no-wrap msgid "" "insttestdir = $(libexecdir)/installed-tests/[project]\n" "\n" "all_test_programs = \\\n" "\ttest-program1 \\\n" "\ttest-program2 \\\n" "\ttest-program3 \\\n" "\t$(NULL)\n" "if BUILD_MODULAR_TESTS\n" "TESTS = $(all_test_programs)\n" "noinst_PROGRAMS = $(TESTS)\n" "endif\n" "\n" "if BUILDOPT_INSTALL_TESTS\n" "insttest_PROGRAMS = $(all_test_programs)\n" "\n" "testmetadir = $(datadir)/installed-tests/[project]\n" "testmeta_DATA = $(all_test_programs:=.test)\n" "\n" "testdatadir = $(insttestdir)\n" "testdata_DATA = $(test_files)\n" "\n" "testdata_SCRIPTS = $(test_script_files)\n" "endif\n" "\n" "EXTRA_DIST = $(test_files)\n" "\n" "%.test: % Makefile\n" "\t$(AM_V_GEN) (echo '[Test]' > $@.tmp; \\\n" "\techo 'Type=session' >> $@.tmp; \\\n" "\techo 'Exec=$(insttestdir)/$<' >> $@.tmp; \\\n" "\tmv $@.tmp $@)" msgstr "" "insttestdir = $(libexecdir)/installed-tests/[project]\n" "\n" "all_test_programs = \\\n" "\ttest-program1 \\\n" "\ttest-program2 \\\n" "\ttest-program3 \\\n" "\t$(NULL)\n" "if BUILD_MODULAR_TESTS\n" "TESTS = $(all_test_programs)\n" "noinst_PROGRAMS = $(TESTS)\n" "endif\n" "\n" "if BUILDOPT_INSTALL_TESTS\n" "insttest_PROGRAMS = $(all_test_programs)\n" "\n" "testmetadir = $(datadir)/installed-tests/[project]\n" "testmeta_DATA = $(all_test_programs:=.test)\n" "\n" "testdatadir = $(insttestdir)\n" "testdata_DATA = $(test_files)\n" "\n" "testdata_SCRIPTS = $(test_script_files)\n" "endif\n" "\n" "EXTRA_DIST = $(test_files)\n" "\n" "%.test: % Makefile\n" "\t$(AM_V_GEN) (echo '[Test]' > $@.tmp; \\\n" "\techo 'Type=session' >> $@.tmp; \\\n" "\techo 'Exec=$(insttestdir)/$<' >> $@.tmp; \\\n" "\tmv $@.tmp $@)" #. (itstool) path: section/title #: C/unit-testing.page:171 #, fuzzy msgid "Leak Checking" msgstr "Έλεγχος διαρροής:" #. (itstool) path: section/p #: C/unit-testing.page:173 msgid "" "Once unit tests with high code coverage have been written, they can be run " "under various dynamic analysis tools, such as Valgrind 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 for more information, including build " "system integration instructions." msgstr "" #. (itstool) path: section/p #: C/unit-testing.page:183 msgid "" "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.)" msgstr "" #. (itstool) path: section/title #: C/unit-testing.page:193 #, fuzzy msgid "Test Generation" msgstr "Παραγωγή" #. (itstool) path: section/p #: C/unit-testing.page:195 msgid "" "Certain types of code are quite repetitive, and require a lot of unit tests " "to gain good coverage; but are appropriate for test data generation, 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." msgstr "" #. (itstool) path: section/title #: C/unit-testing.page:205 msgid "JSON" msgstr "JSON" #. (itstool) path: section/p #: C/unit-testing.page:207 msgid "" "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 Walbottle can be " "used to generate test vectors for all types of valid and invalid input " "according to the schema." msgstr "" #. (itstool) path: section/p #: C/unit-testing.page:216 msgid "" "Every type of JSON document should have a JSON Schema defined for it, which can then be passed to " "Walbottle to generate test vectors:" msgstr "" #. (itstool) path: section/code #: C/unit-testing.page:221 #, no-wrap msgid "" "\n" "json-schema-generate --valid-only schema.json\n" "json-schema-generate --invalid-only schema.json" msgstr "" "\n" "json-schema-generate --valid-only schema.json\n" "json-schema-generate --invalid-only schema.json" #. (itstool) path: section/p #: C/unit-testing.page:225 msgid "" "These test vectors can then be passed to the code under test in its unit " "tests. The JSON instances generated by --valid-only should be " "accepted; those from --invalid-only should be rejected." msgstr "" #. (itstool) path: section/title #: C/unit-testing.page:234 #, fuzzy msgid "Writing Testable Code" msgstr "Εγγραφή..." #. (itstool) path: section/p #: C/unit-testing.page:236 msgid "" "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:" msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:242 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:246 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:260 msgid "Expose utility functions where they might be generally useful." msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:263 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/unit-testing.page:274 msgid "The topic of software testability is covered in the following articles:" msgstr "" #. (itstool) path: item/p #: C/unit-testing.page:278 msgid "" "Design " "for testability" msgstr "" "Design " "for testability" #. (itstool) path: item/p #: C/unit-testing.page:282 msgid "" "Software " "testability" msgstr "" "Software " "testability" #. (itstool) path: item/p #: C/unit-testing.page:286 msgid "" "Dependency " "injection" msgstr "" "Dependency " "injection" #. (itstool) path: item/p #: C/unit-testing.page:290 msgid "" "Software " "design for testing" msgstr "" "Software " "design for testing" #. (itstool) path: info/desc #: C/version-control.page:17 #, fuzzy msgid "Source code version control with git" msgstr "Έλεγχος έκδοσης Git" #. (itstool) path: page/title #: C/version-control.page:20 #, fuzzy msgid "Version Control" msgstr "Έλεγχος εκδόσεων" #. (itstool) path: synopsis/p #: C/version-control.page:25 msgid "" "git is used for version control for all GNOME projects. This page assumes " "good working knowledge of git; some introductory material is available here, and a git cheatsheet is here." msgstr "" #. (itstool) path: item/p #: C/version-control.page:34 msgid "" "Make atomic, revertable commits. ()" msgstr "" #. (itstool) path: item/p #: C/version-control.page:38 msgid "" "Include full reasoning in commit messages, plus links to relevant bug " "reports or specifications. ()" msgstr "" #. (itstool) path: item/p #: C/version-control.page:43 msgid "" "Keep large changes, such as renames, in separate commits. ()" msgstr "" #. (itstool) path: item/p #: C/version-control.page:47 msgid "" "Merge changes from feature branches by rebasing. ()" msgstr "" #. (itstool) path: section/title #: C/version-control.page:55 msgid "Use of Git" msgstr "Χρήση του Git" #. (itstool) path: section/p #: C/version-control.page:57 msgid "Most GNOME repositories follow these rules:" msgstr "" #. (itstool) path: item/p #: C/version-control.page:61 msgid "" "No forced pushes. Except for branches with the wip/ prefix " "(work-in-progress), the commits’ history must not be modified, as " "contributors rely on it." msgstr "" #. (itstool) path: item/p #: C/version-control.page:66 msgid "" "Rebase commits rather than merging, to have a linear history (which is " "easier to follow)." msgstr "" #. (itstool) path: item/p #: C/version-control.page:70 msgid "" "Work on feature branches on GNOME git in wip/ 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 wip/nickname/feature." msgstr "" #. (itstool) path: item/p #: C/version-control.page:76 msgid "" "Hide sausage making by squashing commits before merging." msgstr "" #. (itstool) path: section/title #: C/version-control.page:84 #, fuzzy msgid "Guidelines for Making Commits" msgstr "Οδηγίες" #. (itstool) path: section/p #: C/version-control.page:86 msgid "" "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 git log --oneline) should be copied into " "the bug report once the commit has been pushed, so it is easy to find one " "from the other." msgstr "" #. (itstool) path: section/p #: C/version-control.page:98 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/version-control.page:106 msgid "The following principles give the reasoning for all the advice above:" msgstr "" #. (itstool) path: item/p #: C/version-control.page:110 msgid "" "Each commit should take the repository from one working state to another, " "otherwise bisection is impossible." msgstr "" #. (itstool) path: item/p #: C/version-control.page:116 msgid "" "Each commit should be individually revertable. If it later turns out that " "the commit was a bad idea, git revert commit ID should " "take the repository from a working state to another working state." msgstr "" #. (itstool) path: item/p #: C/version-control.page:122 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/version-control.page:129 msgid "" "Each commit should be written once, and designed to be read many times, by " "many reviewers and future programmers." msgstr "" #. (itstool) path: section/title #: C/version-control.page:137 msgid "Merging Procedure" msgstr "Διαδικασία συγχώνευσης" #. (itstool) path: section/p #: C/version-control.page:139 msgid "" "To merge a feature branch named my-branch into master, use the " "following commands:" msgstr "" #. (itstool) path: section/code #: C/version-control.page:143 #, no-wrap msgid "" "\n" "git checkout master\n" "git pull\n" "\n" "git checkout wip/my-branch\n" "git rebase --interactive master\n" "# Ensure the rebase is successful; test the changes\n" "\n" "git checkout master\n" "git merge wip/my-branch\n" "git push\n" "\n" "# wip/my-branch can now be deleted\n" "git push origin :wip/my-branch\n" "git branch -D wip/my-branch" msgstr "" "\n" "git checkout master\n" "git pull\n" "\n" "git checkout wip/my-branch\n" "git rebase --interactive master\n" "# Ensure the rebase is successful; test the changes\n" "\n" "git checkout master\n" "git merge wip/my-branch\n" "git push\n" "\n" "# wip/my-branch can now be deleted\n" "git push origin :wip/my-branch\n" "git branch -D wip/my-branch" #. (itstool) path: item/p #: C/version-control.page:164 msgid "" "Git best " "practices" msgstr "" #. (itstool) path: item/p #: C/version-control.page:167 msgid "" "Git FAQ" msgstr "" #. (itstool) path: item/p #: C/version-control.page:170 msgid "" "Atlassian git " "tutorial" msgstr "" #. (itstool) path: item/p #: C/version-control.page:173 msgid "" "Official git tutorial" msgstr "" #. (itstool) path: item/p #: C/version-control.page:176 msgid "Interactive git tutorial" msgstr "" #. (itstool) path: item/p #: C/version-control.page:179 msgid "" "git-tower tutorial" msgstr "" #. (itstool) path: info/desc #: C/versioning.page:17 #, fuzzy msgid "Versioning and releasing libraries and applications" msgstr "Μεταφράστε και τοπικοποιήστε εφαρμογές και βιβλιοθήκες" #. (itstool) path: synopsis/p #: C/versioning.page:25 msgid "" "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." msgstr "" #. (itstool) path: item/p #: C/versioning.page:32 msgid "" "Libraries and applications have a package version of the form major." "minor.micro. ()" msgstr "" #. (itstool) path: item/p #: C/versioning.page:36 msgid "" "Libraries additionally have a libtool version of the form current:" "revision:age. ()" msgstr "" #. (itstool) path: item/p #: C/versioning.page:40 msgid "" "Version numbers should be updated for each release (using release and post-" "release increments). ()" msgstr "" #. (itstool) path: item/p #: C/versioning.page:44 msgid "" "Package versions should be incremented for feature changes or additions. " "()" msgstr "" #. (itstool) path: item/p #: C/versioning.page:48 msgid "" "Libtool versions should be updated for API changes or additions. ()" msgstr "" #. (itstool) path: item/p #: C/versioning.page:52 msgid "" "Even/odd minor package versions can be used respectively for stable/" "unstable releases. ()" msgstr "" #. (itstool) path: section/title #: C/versioning.page:60 #, fuzzy msgid "Package Versioning" msgstr "Εκδόσεις" #. (itstool) path: section/p #: C/versioning.page:62 msgid "" "Both libraries and applications have a package version of the form major." "minor.micro." msgstr "" #. (itstool) path: section/p #: C/versioning.page:67 msgid "" "The package version number is that passed to AC_INIT(), 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 parallel installability). Package versions are updated by the following rules:" msgstr "" #. (itstool) path: item/p #: C/versioning.page:77 msgid "" "If breaking API compatibility 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." msgstr "" #. (itstool) path: item/p #: C/versioning.page:83 msgid "" "Otherwise, if changing or adding a feature, or adding any API, increment " "minor and set micro to 0." msgstr "" #. (itstool) path: item/p #: C/versioning.page:87 msgid "" "Otherwise (if making a release containing only bug fixes and translation " "updates), increment micro." msgstr "" #. (itstool) path: section/p #: C/versioning.page:93 msgid "" "Note that the minor version number should be updated if any API is added." msgstr "" #. (itstool) path: section/title #: C/versioning.page:99 #, fuzzy msgid "Libtool Versioning" msgstr "Εκδόσεις" #. (itstool) path: section/p #: C/versioning.page:101 msgid "" "Libraries have two version numbers: a libtool version which tracks ABI " "backwards compatibility (see ), 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." msgstr "" #. (itstool) path: section/p #: C/versioning.page:112 msgid "" "A good overview of libtool versioning, and the differences from package " "versioning, is given in the Autotools Mythbuster; another is in the libtool manual." msgstr "" #. (itstool) path: section/p #: C/versioning.page:121 msgid "" "To update the libtool version, follow the algorithm given in the comments " "below. This is a typical configure.ac snippet for setting up " "libtool versioning:" msgstr "" #. (itstool) path: section/code #: C/versioning.page:127 #, no-wrap msgid "" "\n" "# Before making a release, the LT_VERSION string should be modified. The\n" "# string is of the form c:r:a. Follow these instructions sequentially:\n" "# 1. If the library source code has changed at all since the last update, then\n" "# increment revision (‘c:r:a’ becomes ‘c:r+1:a’).\n" "# 2. If any interfaces have been added, removed, or changed since the last\n" "# update, increment current, and set revision to 0.\n" "# 3. If any interfaces have been added since the last public release, then\n" "# increment age.\n" "# 4. If any interfaces have been removed or changed since the last public\n" "# release, then set age to 0.\n" "AC_SUBST([LT_VERSION],[0:0:0])" msgstr "" "\n" "# Before making a release, the LT_VERSION string should be modified. The\n" "# string is of the form c:r:a. Follow these instructions sequentially:\n" "# 1. If the library source code has changed at all since the last update, then\n" "# increment revision (‘c:r:a’ becomes ‘c:r+1:a’).\n" "# 2. If any interfaces have been added, removed, or changed since the last\n" "# update, increment current, and set revision to 0.\n" "# 3. If any interfaces have been added since the last public release, then\n" "# increment age.\n" "# 4. If any interfaces have been removed or changed since the last public\n" "# release, then set age to 0.\n" "AC_SUBST([LT_VERSION],[0:0:0])" #. (itstool) path: section/p #: C/versioning.page:140 msgid "" "The following snippet can be used in a Makefile.am to pass that " "version info to libtool:" msgstr "" #. (itstool) path: section/code #: C/versioning.page:144 #, no-wrap msgid "my_library_la_LDFLAGS = -version-info $(LT_VERSION)" msgstr "my_library_la_LDFLAGS = -version-info $(LT_VERSION)" #. (itstool) path: section/title #: C/versioning.page:148 msgid "Stable and Unstable Package Versions" msgstr "" #. (itstool) path: section/p #: C/versioning.page:150 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/versioning.page:158 msgid "" "A new micro stable version (e.g. 3.20.0 → 3.20.1) doesn’t add new " "features, only translation updates and bug fixes. On the other hand, " "unstable 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." msgstr "" #. (itstool) path: section/p #: C/versioning.page:166 msgid "The libtool version should be updated only for stable package versions." msgstr "" #. (itstool) path: section/title #: C/versioning.page:172 #, fuzzy msgid "Release Process" msgstr "Σε εξέλιξη" #. (itstool) path: section/p #: C/versioning.page:174 msgid "" "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)." msgstr "" #. (itstool) path: section/p #: C/versioning.page:181 msgid "" "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." msgstr "" #. (itstool) path: section/p #: C/versioning.page:189 msgid "" "The release process (based on the GNOME release process):" msgstr "" #. (itstool) path: item/p #: C/versioning.page:195 msgid "Make sure code is up to date: git pull" msgstr "" #. (itstool) path: item/p #: C/versioning.page:199 msgid "Make sure you have no local changes: git status" msgstr "" #. (itstool) path: item/p #: C/versioning.page:202 msgid "" "If the release is for a stable package version, increment the libtool " "version number in configure.ac (if it exists)" msgstr "" #. (itstool) path: item/p #: C/versioning.page:206 #, fuzzy msgid "Add an entry to the NEWS file" msgstr "Απαιτείται πιστοποίηση για προσθήκη καταχώρισης στο αρχείο /etc/fstab" #. (itstool) path: item/p #: C/versioning.page:210 msgid "" "Run ./autogen.sh && make && make install && " "make distcheck and ensure it succeeds" msgstr "" #. (itstool) path: item/p #: C/versioning.page:216 msgid "" "Fix any issues which come up, commit those changes, and restart at step 3" msgstr "" #. (itstool) path: item/p #: C/versioning.page:222 msgid "" "If make distcheck finishes with “[archive] is ready for " "distribution”, run git commit -a -m \"Release version x.y.z\" " "(where ‘x.y.z’ is the package version number)" msgstr "" #. (itstool) path: item/p #: C/versioning.page:228 C/versioning.page:263 msgid "Run git push" msgstr "Εκτελέστε git push" #. (itstool) path: item/p #: C/versioning.page:232 msgid "" "If that fails due to other commits having been pushed in the meantime, run " "git pull to merge your commit on the branch followed by a second " "git push. This is an exception to the GNOME guideline to have a " "linear Git history (). If you " "prefer to have a linear history, you need to restart at step 1." msgstr "" #. (itstool) path: item/p #: C/versioning.page:242 msgid "" "Tag the release: git tag -s x.y.z (where ‘x.y.z’ is the package " "version number)" msgstr "" "Δώστε μια ετικέτα στην έκδοση: git tag -s x.y.z (όπου ‘x.y.z’ " "είναι ο αριθμός έκδοσης)" #. (itstool) path: item/p #: C/versioning.page:246 msgid "" "Run git push origin x.y.z (where ‘x.y.z’ is the package version " "number)" msgstr "" "Εκτελέστε git push origin x.y.z (όπου ‘x.y.z’ είναι ο αριθμός " "έκδοσης)" #. (itstool) path: section/p #: C/versioning.page:252 msgid "" "The release is now complete, and the post-release version increment can be " "done:" msgstr "" #. (itstool) path: item/p #: C/versioning.page:257 msgid "Increment the package version number in configure.ac" msgstr "" #. (itstool) path: item/p #: C/versioning.page:260 msgid "Run git commit -a -m \"Post-release version increment\"" msgstr "" "Εκτελέστε git commit -a -m \"Post-release version increment\"" #. (itstool) path: section/p #: C/versioning.page:268 msgid "" "The package archive generated by make distcheck can now be " "uploaded to download.gnome.org or distributed in other ways." msgstr "" #. (itstool) path: info/desc #: C/writing-good-code.page:25 msgid "Good, readable code keeps the project maintainable" msgstr "" #. (itstool) path: page/title #: C/writing-good-code.page:28 msgid "The Importance of Writing Good Code" msgstr "" #. (itstool) path: page/p #: C/writing-good-code.page:30 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/writing-good-code.page:43 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/writing-good-code.page:51 msgid "" "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." msgstr "" #. (itstool) path: page/p #: C/writing-good-code.page:58 msgid "" "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 communication, 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." msgstr "" #. (itstool) path: page/p #: C/writing-good-code.page:71 msgid "The following are some important qualities of good code:" msgstr "" #. (itstool) path: item/title #: C/writing-good-code.page:77 msgid "Cleanliness" msgstr "" #. (itstool) path: item/p #: C/writing-good-code.page:78 msgid "" "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." msgstr "" #. (itstool) path: item/title #: C/writing-good-code.page:87 msgid "Consistency" msgstr "Συνοχή" #. (itstool) path: item/p #: C/writing-good-code.page:88 msgid "" "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 looks the same in two " "places should work the same, too." msgstr "" #. (itstool) path: item/title #: C/writing-good-code.page:99 msgid "Extensibility" msgstr "Επεκτασιμότητα" #. (itstool) path: item/p #: C/writing-good-code.page:100 msgid "" "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." msgstr "" #. (itstool) path: item/title #: C/writing-good-code.page:112 msgid "Correctness" msgstr "" #. (itstool) path: item/p #: C/writing-good-code.page:113 msgid "" "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." msgstr "" #. (itstool) path: section/title #: C/writing-good-code.page:126 msgid "Book References" msgstr "Αναφορές βιβλίων" #. (itstool) path: item/p #: C/writing-good-code.page:129 msgid "" "Code Complete, by Steve McConnell." msgstr "" "Code Complete, από Steve McConnell." #. (itstool) path: item/p #: C/writing-good-code.page:132 msgid "" " Refactoring: " "Improving the Design of Existing Code , by Martin Fowler." msgstr "" " Refactoring: " "Improving the Design of Existing Code , από Martin Fowler." #. (itstool) path: item/p #: C/writing-good-code.page:137 msgid "" " Design " "Patterns: Elements of Reusable Object-Oriented Software , by Erich " "Gamma, Richard Helm, Ralph Johnson and John Vlissides." msgstr "" " Design " "Patterns: Elements of Reusable Object-Oriented Software , από Erich " "Gamma, Richard Helm, Ralph Johnson και John Vlissides." #. (itstool) path: item/p #: C/writing-good-code.page:142 msgid "" " " "Object-Oriented Design Heuristics , by Arthur Riel." msgstr "" " " "Object-Oriented Design Heuristics , από Arthur Riel."